Bash: Как определить, открыт ли терминал сторонним приложением

Я хочу, чтобы мой bash-скрипт (в частности, мой ~/.bashrc) делал что-то, только если терминал был открыт мной непосредственно, и делал что-то еще, если он был открыт через приложение, например. Кодекс VS. Как я могу определить, в чем дело? Есть переменная для этого? Заранее спасибо.

9
задан 1 June 2018 в 23:52

4 ответа

Вы, вероятно, могли бы сделать это, пройдя назад по наследству оболочки и выяснив, была ли она запущена чем-то, что приравнивается к «вам», или другой программой.

Получите PID оболочки (идентификатор процесса), а затем его PPID (идентификатор родительского процесса). Продолжайте идти вверх, пока не доберетесь до чего-то, что скажет вам, откуда это произошло. Возможно, вам придется поэкспериментировать на вашей системе - по крайней мере, я не знаю, будет ли она универсальной.

Например, в моей системе получить PID оболочки и использовать ps, чтобы показать, что это bash:

$ echo $
18852
$ ps --pid 18852
  PID TTY          TIME CMD
18852 pts/1    00:00:00 bash

Получить PPID 18852:

$ ps -o ppid= -p 18852
18842

Узнайте, что такое PPID (18842):

$ ps --pid 18842
  PID TTY          TIME CMD
18842 ?        00:00:02 gnome-terminal

Мы можем видеть его gnome-терминал, то есть эмулятор терминала / окно терминала. Может быть, этого достаточно, если ваша оболочка, запущенная другой программой, не работает в окне эмулятора терминала.

Если это недостаточно хорошо, поднимитесь на другой уровень:

$ ps -o ppid= -p 18842
 2313
$ ps --pid 2313
  PID TTY          TIME CMD
 2313 ?        00:00:00 init

Это говорит нам о том, что gnome-terminal был начат init. Я подозреваю, что ваша оболочка, запущенная другой программой, будет иметь что-то другое.

0
ответ дан 1 June 2018 в 23:52

Вот мои 2 цента. Просто добавьте его в свой .bashrc. Замените terminals на ваши любимые терминалы и команду export на ваши.

run_in_terminal(){
  local parent_command="$(ps --no-headers --pid $PPID -o command | awk '{print $1;}')"
  local parent="$(basename $parent_command)"
  local terminals=( gnome-terminal st xterm ) # list your favorite terminal here
  if [[ ${terminals[*]} =~ ${parent} ]]; then
    # Your commands to run if in terminal
    export MY_VAR_IN_TERMINAL="test"
  fi
}
run_in_terminal
0
ответ дан 1 June 2018 в 23:52

Насколько Код Visual Studio идет, по-видимому, существует способ установить переменные новой среды для интегрированного терминала. Так, настроенная Visual Studio для использования этой конфигурации:

"terminal.integrated.env.linux": {
  "visual_studio": "true"
}

И в ~/.bashrc:

if [ -n "$visual_studio" ]; then
    # do something for Visual Studio
else
    # do something else for other types of terminal
fi

В целом Вы могли полагаться на среду, данную bash процесс. Например, $TERM переменная, и выполненный подобное if..then...else...fi ответвление для [ "$TERM" = "xterm" ] или что-то еще. На основе от случая к случаю можно исследовать различия в среде через выполнение env в каждой консоли сохраните это в файл как в env > output_console1.txt, и diff output_console1.txt output_console2.txt как предложено десертом в комментариях.

9
ответ дан 23 November 2019 в 04:48

Если Вы говорите об одном определенном стороннем приложении, то используйте переменную среды. Большинство программ проведет всю среду, неизменную когда они fork+exec новые процессы.

Так, запустите это приложение с пользовательского огибающего var, на который можно проверить. например, сделайте псевдоним для него как alias vs=RUNNING_FROM_VSCODE=1 VSCode, или сделайте сценарий обертки как это:

#!/bin/sh
export RUNNING_FROM_VSCODE=1
exec VSCode "$@"

Затем в Вашем .bashrc, можно сделать

if (($RUNNING_FROM_VSCODE)); then
   echo "started from inside VSCode"
   # RUNNING_FROM_VSCODE=0  # optional if you only want the immediate child
fi

Оператор арифметики удара (( )) верно, если выражение оценивает к ненулевому целому числу (который является, почему я использовал 1 выше). Пустая строка (для var ENV сброса) является ложью. Это хорошо для логических переменных удара, но Вы могли столь же легко использовать true и проверьте на него с традиционным POSIX

if [ "x$RUNNING_FROM_VSCODE" = "xtrue" ]; then
   echo "started from inside VSCode"
fi

Если Ваше приложение главным образом очищает среду для своих детей, но все еще переходит $PATH неизменный, Вы могли использовать это в своей обертке:

#!/bin/sh
export PATH="$PATH:/dev/null/RUNNING_FROM_VSCODE"
exec VSCode "$@"

и проверьте на него с соответствием шаблона как удар [[ "${PATH%RUNNING_FROM_VSCODE}" != "$PATH" ]] проверять при разделении суффикса от ПУТИ изменяет его.

Это должно безопасно сделать один дополнительный поиск каталога, когда программа ищет незнакомые внешние команды. /dev/null определенно не каталог в любой системе, таким образом, безопасно использовать в качестве поддельного каталога, который быстро приведет к ENOTDIR если поиски ПУТИ не находят то, что они ищут в более ранних записях ПУТИ.

2
ответ дан 23 November 2019 в 04:48

Другие вопросы по тегам:

Похожие вопросы: