Я хочу, чтобы мой bash-скрипт (в частности, мой ~/.bashrc
) делал что-то, только если терминал был открыт мной непосредственно, и делал что-то еще, если он был открыт через приложение, например. Кодекс VS. Как я могу определить, в чем дело? Есть переменная для этого? Заранее спасибо.
Вы, вероятно, могли бы сделать это, пройдя назад по наследству оболочки и выяснив, была ли она запущена чем-то, что приравнивается к «вам», или другой программой.
Получите 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
. Я подозреваю, что ваша оболочка, запущенная другой программой, будет иметь что-то другое.
Вот мои 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
Насколько Код 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
как предложено десертом в комментариях.
Если Вы говорите об одном определенном стороннем приложении, то используйте переменную среды. Большинство программ проведет всю среду, неизменную когда они 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
если поиски ПУТИ не находят то, что они ищут в более ранних записях ПУТИ.