6

How can I determine if a script was invoked from a command line or via double-click in file manager (Nautilis)?

If the former, I still have a command prompt when the script finishes, but if it was double-clicked (or executed via a .desktop file), the script executes in a window and then disappears. I want the window to remain open with a command prompt.

I figure the script could make this check and either do nothing - if invoked from a command line - or exec bash at the end if invoked via double-click or .desktop.

Haven't been successful using methods to check if interactive or not or tty.

  • 1
    Have your .desktop file call your script in a command terminal and execute it. The first answer here with the line Exec=gnome-terminal -e "bash -c 'echo hello;$SHELL'" worked well when I tested it on my system. I changed the echo hello to my own script. – Terrance Feb 5 '16 at 7:20
  • Note to future viewers, while the accepted answer by muru worked, the method in the comment by @Terrance is what I ultimately used. – tcashin Apr 4 '18 at 18:08
6

You can check if the parent process is the shell. For example:

#! /bin/bash

if [[ $(readlink -f /proc/$(ps -o ppid:1= -p $$)/exe) != $(readlink -f "$SHELL") ]]
then 
    echo "Starting the shell..."
    exec "$SHELL"
else
    echo "Not starting a shell."
fi

ps -o ppid:1= -p $$ prints the PID of the parent process (ppid) of the current process (-p $$). A readlink on /proc/<pid>/exe should print the path to the executable, which would be the shell if you ran it in a shell, or something else otherwise.


Another possibility is the SHLVL variable, which indicates how nested the current the shell instance is. If run within a shell, the script should have SHLVL 2 or greater. When run by double clicking, or from a desktop launcher, it should be 1:

#! /bin/bash

if (( SHLVL > 1 ))
then 
    echo "Starting the shell..."
    exec "$SHELL"
else
    echo "Not starting a shell."
fi
  • The SHLVL option doesn't work for /bin/sh (dash) but the first option seems to work for both dash and bash. – tcashin Feb 8 '16 at 18:56
  • @tcashin well, nobody uses dash as their interactive shell, and the question itself is tagged bash. – muru Feb 8 '16 at 19:30
  • +1 for SHLVL as a platform-independent bash solution – Ed Randall Oct 9 '18 at 16:02
1

You can check if the shell script was run on a terminal by analyzing the output of tty command.

#! /bin/bash

if [[ $(tty) =~ "not a tty" ]]
then
    echo "Not running on terminal"

else
    echo "Running on terminal"
fi
  • 1
    That test can be simplified with -t 0 instead of $(tty) =~ ..., IIRC. – muru Apr 3 '18 at 10:34
0

I checked the differences between the environment when running a script from the terminal and the environment when running a script by double-clicking it in Files;

When you run a script by double clicking in Files the $VTE_VERSION variable is unset, so you can hook to it to decide whether to replace the current Bash instance with an interactive one or not.

That is, just put this at the end of your script:

#! /bin/bash
# ...
[ ! -z $VTE_VERSION ] && exec bash

To make this work also in case the script is run from a desktop file, change the desktop file's Exec= line from say:

Exec=/path/to/script

To:

Exec=sh -c '/path/to/script; exec bash'

This way /path/to/script will be executed and sh will be replaced by Bash upon /path/to/script's completion.

0

When double clicked from Nautilus you won't have the entire environment setup like you do in a regular terminal session. I use this boilerplate code to prevent crashes: enter link description here . You can adapt it to your needs:

# $TERM variable may be missing when called via desktop shortcut
CurrentTERM=$(env | grep TERM)
if [[ $CurrentTERM == "" ]] ; then
    notify-send --urgency=critical "$0 cannot be run from GUI without TERM environment variable."
    exit 1
fi

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.