Существует 3 подхода к нахождению имени исполняемого файла текущей оболочки:
Обратите внимание, что все 3 подхода можно обмануть, если исполняемым файлом оболочки является / bin / sh
, но на самом деле это, например, переименованный bash
(что часто случается).
Таким образом, на ваш второй вопрос о том, подойдет ли вывод ps
, будет дан ответ « не всегда ».
echo $ 0
- напечатает имя программы ... которое в случае оболочки является фактической оболочкой
ps -ef | grep $$ | grep -v grep
- Это будет искать идентификатор текущего процесса в списке запущенных процессов. Поскольку текущий процесс является оболочкой, он будет включен.
Это ненадежно на 100%, так как у вас могут быть ДРУГИЕ процессы, у которых в листинге ps
указан тот же номер, что и в идентификаторе процесса оболочки, особенно если этот идентификатор - маленький # (например, если PID оболочки равен "5 ", вы можете найти процессы с именами" java5 "или" perl5 "в том же выводе grep
!). Это вторая проблема с подходом «ps», помимо невозможности полагаться на имя оболочки.
echo $ SHELL
- Путь к текущей оболочке сохраняется как переменная SHELL
для любой оболочки. Предостережение для этого заключается в том, что если вы запускаете оболочку явно как подпроцесс (например, это не ваша оболочка входа в систему), вместо этого вы получите значение оболочки входа в систему. Если это возможно, используйте подход ps
или $ 0
.
Если, однако, исполняемый файл не соответствует вашей реальной оболочке (например, / bin / sh
на самом деле bash или ksh), вам нужна эвристика. Вот некоторые переменные среды, специфичные для различных оболочек:
$ версия
установлена на tcsh
$ BASH
установлена на bash
$ shell
(нижний регистр) установлена на фактическую оболочку имя в csh или tcsh
$ ZSH_NAME
установлено на zsh
ksh имеет $ PS3
и $ PS4
, тогда как обычная оболочка Борна ( sh
) установлены только $ PS1
и $ PS2
. Как правило, это труднее всего различить - ЕДИНСТВЕННАЯ разница во всем наборе переменных среды между sh
и ksh
, которые мы установили на Solaris boxen, составляет $ ERRNO
, $ FCEDIT
, $ LINENO
, $ PPID
, $ PS3
, $ PS4
, $ RANDOM
, $ SECONDS
, $ TMOUT
.
ps - самый надежный метод. Установка envar SHELL не гарантируется, и даже если это так, ее можно легко подделать
Вы можете попробовать:
ps | grep `echo $$` | awk '{ print $4 }'
Или:
echo $SHELL
echo $$ # Gives the Parent Process ID
ps -ef | grep $$ | awk '{print $8}' #use the PID to see what the process is.
ps -p $$
должны работать везде, где решения, включающие ps -ef
и grep
do (в любом варианте Unix, который поддерживает параметры POSIX для ps
) и не страдают от введенных ложных срабатываний путем поиска последовательности цифр, которые могут появиться в другом месте.
На Mac OS X (и FreeBSD):
ps -p $$ -axco command | sed -n '$p'