Вопрос Как проверить, был ли сценарий запущен через командную строку или дважды щелкнул?


Как определить, был ли сценарий выведен из командной строки или с помощью двойного щелчка в диспетчере файлов (Nautilis)?

Если первое, у меня все еще есть командное приглашение, когда скрипт заканчивается, но если он был дважды щелкнул (или выполнил файл .desktop), скрипт выполнится в окне и затем исчезнет. Я хочу, чтобы окно оставалось открытым с помощью командной строки.

Я полагаю, скрипт может сделать эту проверку и ничего не делать - если вызывается из командной строки - или exec bash в конце, если вызывается с помощью двойного щелчка или .desktop.

Не удалось использовать методы для проверки интерактивности или отсутствия или tty.


5
2018-02-05 06:43


происхождения


Иметь свой .desktop файл вызывает ваш скрипт в командном терминале и выполняет его. Первый ответ Вот  с линией Exec=gnome-terminal -e "bash -c 'echo hello;$SHELL'" работал хорошо, когда я тестировал его в своей системе. Я изменил echo hello к моему собственному сценарию. - Terrance
Обратите внимание на будущих зрителей, в то время как принятый ответ muru работал, метод в комментарии @Terrance - это то, что я в конечном счете использовал. - tcashin


ответы:


Вы можете проверить, является ли родительский процесс оболочкой. Например:

#! /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 $$ печатает PID родительского процесса (ppid) текущего процесса (-p $$). readlink на /proc/<pid>/exe должен печатать путь к исполняемому файлу, который будет оболочкой, если вы запустили его в оболочке или что-то еще в противном случае.


Другая возможность SHLVL переменная, который указывает, как вложен текущий экземпляр оболочки. Если запустить внутри оболочки, сценарий должен иметь SHLVL 2 или больше. При запуске двойным щелчком или с панели запуска на рабочем столе она должна быть 1:

#! /bin/bash

if (( SHLVL > 1 ))
then 
    echo "Starting the shell..."
    exec "$SHELL"
else
    echo "Not starting a shell."
fi

5
2018-02-05 07:31



Опция SHLVL не работает для / bin / sh (тире), но первый вариант, похоже, работает как для тире, так и для bash. - tcashin
@tcashin хорошо, никто не использует dash как их интерактивная оболочка, и сам вопрос помечен bash, - muru


Вы можете проверить, был ли сценарий оболочки запущен на терминале, анализируя вывод TTY команда.

#! /bin/bash

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

else
    echo "Running on terminal"
fi

1
2018-04-03 09:17



Этот тест можно упростить с помощью -t 0вместо $(tty) =~ ..., IIRC. - muru


Я проверил различия между средой при запуске скрипта из терминала и среды при запуске скрипта, дважды щелкнув его в файлах;

Когда вы запускаете скрипт, дважды щелкнув «Файлы» $VTE_VERSION переменная не установлена, поэтому вы можете подключиться к ней, чтобы решить, следует ли заменить текущий экземпляр Bash интерактивным или нет.

То есть, просто поместите это в конец вашего скрипта:

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

Чтобы сделать эту работу также в том случае, если сценарий запущен из файла рабочего стола, измените строку Exec = файла рабочего стола, например:

Exec=/path/to/script

Для того, чтобы:

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

Сюда /path/to/script будут выполнены и sh будет заменен Башем на /path/to/scriptзавершение.


0
2018-02-05 06:56





При двойном щелчке от Nautilus у вас не будет всей настройки среды, как в обычной сессии терминала. Я использую этот шаблонный код для предотвращения сбоев: введите ссылку здесь , Вы можете адаптировать его к вашим потребностям:

# $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

0
2018-04-03 10:24