How to Detect Availability of Gui in Bash/Shell

How to detect availability of GUI in Bash/Shell?

On macOS, there's not a clearly appropriate way to check this from a shell, as such. There's a programmatic way, and we can use an interpreted language to take advantage of that.

Here's a little script that outputs one of three states, Mac GUI, Mac non-GUI, or X11:

#!/bin/bash

check_macos_gui() {
command -v swift >/dev/null && swift <(cat <<"EOF"
import Security
var attrs = SessionAttributeBits(rawValue:0)
let result = SessionGetInfo(callerSecuritySession, nil, &attrs)
exit((result == 0 && attrs.contains(.sessionHasGraphicAccess)) ? 0 : 1)
EOF
)
}

if [ "$(uname)" = "Darwin" ]; then
if check_macos_gui; then
echo "Mac GUI session"
elif [ -n "$DISPLAY" ]; then
echo "Mac X11 GUI session"
else
echo "Mac non-GUI session"
fi
elif [ -n "$DISPLAY" ]; then
echo "X11 GUI session"
fi

Macs can have an X server installed, in which case DISPLAY is defined. However, I don't know if your Electron app will work properly in that configuration. So, I detected it separately.

Detect Graphical Login In Bash

You should probably take a look at the XDG autostart specification, which allows you to have applications start upon desktop login. Since bash and other shells do not follow the XDG specs (obviously, they are UNIX shells, not DEs), you essentially achieve what you're looking for, but without worrying about shells at all.

Bash script - determine if script launched in terminal console or gui

The answer by @LeonidMew is incomplete and somewhat incorrect.

You should not detect GUI by presence of STDIN (that's what [ -t 0 ] test does). There are cases when none of STDIN and GUI are available, e.g. when you run the script over ssh session in non-interactive mode. This happens often for CI deploys.

Correct answer heavily depends on your task, in general there are 4 distinct environments:

  1. App is run non-interactively, e.g. from ssh command, spawned as child process without STDIO attached, etc. GUI is missing, STDIN is missing.
  2. App is run interactively from X-session with .desktop file or alike. GUI is present, STDIN is missing.
  3. App is run interactively from linux terminal (ssh, bare text console, hosting recovery console, etc.). GUI is missing, STDIN is present. App can interact with user in text mode via STDIN.
  4. App is run interactively from GUI terminal app, like xterm. GUI is present, STDIN is present.

There are 2 basic tests that can help to identify the environment:

  1. GUI test - whether app can interact with user using graphical windows: test for $DISPLAY env variable.
  2. STDIN test - whether app can interact with user using text console: test for file descriptor 0 (aka STDIN) with if [ -t 0 ]; ...

Combining these two test will give you the environment:

test 1 false + test 2 false: case 1 -- no user interaction available
test 1 true + test 2 false: case 2 -- interact via XWindows
test 1 false + test 2 true: case 3 -- interact via STDIN/console
test 1 true + test 2 true: case 4 -- XWindows or STDIN/console, whichever is preferred

Difference between Git GUI, Git Bash, Git CMD

Git CMD is just like regular Windows command prompt with the git command. It lets you use all of Git features through command line. Useful if you are already familiar with Windows cmd and you only work on Windows.

Git Bash emulates a bash environment on windows. It lets you use all git features in command line plus most of standard unix commands. Useful if you are used to Linux and want to keep the same habits.

Git GUI is a Graphical User Interface letting you use Git without touching command line. It is an alternative among other Git clients. Since Git GUI is very minimal, you could also look at other alternatives if GUIs interest you.

It is up to you to decide which you want to use. As many others, I recommend you to learn Git with command line before switching to a graphical interface. If you don't know which to choose between Git Bash and Git CMD, I'd go for Git Bash since bash is a really useful tool to learn.

How to show a GUI message box from a bash script in linux?

I believe Zenity will do what you want. It's specifically designed for displaying GTK dialogs from the command line, and it's available as an Ubuntu package.

When should I add a GUI?

As with many questions of this type, the answer is that it depends.

If your program/script does just one single thing by receiving a number of inputs from the user, it is better to stick with the non-GUI mode.

If the application is doing more than one thing and if you think that the user will use the application to do a lot of stuff, you may consider using a GUI.

Are you planning to distribute this program to others? Then it is better to provide a GUI.

If the users are non-technical, a GUI is a must!

Thats it.

Installer on bash: how to show GUI messages?

Anything like xmessage or zenity or gxmessage implies external dependencies that you cannot guarantee will be available (unless you can; you haven't said so in your question). To answer one of your questions, NO, there is nothing universal for Linux. Certainly not anything that depends on X, since so many Linux installations are headless.

For "something else", as a general principle, being self-contained is a good idea. That means using something that doesn't even depend on the X Window System. Shell based dialogs are readily available, whether you're in FreeBSD or Linux.

To be truly self-contained as well as portable (even between different distros of Linux, or different server configurations), I'd suggest writing your own dialog manager as a function within your shell script. Something along the lines of this:

#!/usr/bin/env bash

# A supporting function to see test a value against the contents of an array
is_in() {
value=$1; shift
for i in "$@"; do [[ $i == $value ]] && return 0; done
return 1
}

# Simple dialog implementation, no VT100 required,
dialog() {
# $options is an array of options
local i line max=0
# determine dialog width
for line in "${options[@]}"; do [[ ${#line} -gt $max ]] && max=${#line}; done
# draw a line
eval printf '%.s-' {1..$((max+8))}; echo
# print each option
for i in ${!options[@]}; do
printf "| %2d: %-${max}s |\n" "$i" "${options[i]}"
done
eval printf '%.s-' {1..$((max+8))}; echo
response=""
# only accept valid responses
while ! is_in "$response" "${!options[@]}"; do
read -p " Choose: " response
done
return "$response"
}

# Create our list, run the dialog, capture the result,
options=([1]="Hello world" [2]="This is a test")
dialog
result=$?

# And display the result.
echo "RESPONSE: $result / ${options[$result]}"


Related Topics



Leave a reply



Submit