it-swarm-ru.tech

Как проверить, какую оболочку я использую в терминале?

Как проверить, какую оболочку я использую в терминале? Какую оболочку я использую в MacOS?

73
user5837

Несколько способов, от большинства к наименее надежным (и от наиболее к наименее "тяжелым"):

  1. ps -p$$ -ocmd=. (В Solaris это может быть fname вместо cmd. В OSX и BSD должно быть command вместо cmd.)
  2. Проверить $BASH_VERSION, $ZSH_VERSION и ​​другие переменные, специфичные для Shell.
  3. Проверьте $Shell; это последнее средство, так как оно определяет вашу по умолчанию оболочку и не обязательно текущую оболочку.
75
geekosaur

Я обнаружил, что следующие четыре оболочки, которые я установил в своей системе (bash, dash, zsh, csh):

$ ps -p $$

Следующее работает на zsh, bash и dash, но не на csh:

$ echo $0
43
Steven D

Поскольку вопрос касается используемой оболочки и не говорит о потенциальных передаваемых ей аргументах, вот способ избежать их показа:

$ ps -o comm= -p $$
ksh93 
8
jlliagre

Примечание о некоторых более легких реализациях (телефоны Android, busybox и т.д.): ps не всегда поддерживает -p, но вы можете выполнить поиск с помощью команды, подобной ps | grep "^$$ ". (Это регулярное выражение grep однозначно идентифицирует PID, поэтому ложных срабатываний не будет.

6
palswim

Есть два действительно простых способа:

  • Использование команды ps :

    ps -o comm= $$
    

    или

    ps -h -o comm -p $$
    

    где:

    • -h или заканчивая все параметры с помощью = за то, что не отображается заголовок.
    • -o comm для отображения только базового имени процесса (bash вместо /bin/bash).
    • -p <PID> обрабатывать только список с предоставленным списком форм PID.
  • Использование /proc псевдофайловой системы с информацией о процессе:

    cat /proc/$$/comm
    

    Эта опция работает точно так же, как команда ps выше.

    или

    readlink /proc/$$/exe
    

    Эта /proc/PID/exe ссылки на исполняемый файл, который в этом случае будет указывать на/bin/bash,/bin/ksh и т. д.

    Для получения только имени оболочки вы можете просто использовать

    basename $(readlink /proc/$$/exe)
    

    Это единственная опция, которая всегда будет давать тот же результат, даже если вы находитесь в скрипте, исходном коде или терминале, как ссылки на двоичный файл используемого интерпретатора Shell.

    Предупреждение Вы должны знать, что это покажет окончательный двоичный файл, поэтому ksh может быть связан с ksh93 или sh с bash.

Использование /proc действительно полезен через /proc/self, который ссылается на PID текущей команды.

5
David Goitia

Смесь всех остальных ответов, совместимых с Mac (comm), Solaris (fname) и Linux (cmd):

ps -p$$ -o cmd="",comm="",fname="" 2>/dev/null | sed 's/^-//' | grep -oE '\w+' | head -n1
3
sebastien

Если вы сохранили его в переменных окружения, вы можете использовать следующее:

echo $Shell
2
jasonleonhard

Pid запущенной оболочки дается переменной $$ (в большинстве оболочек).

whichsh="`ps -o pid,args| awk '$1=='"$$"'{print $2}'`"
echo "$whichsh"

Использование обратных галочек для работы jsh (Heirlomm Shell).

Во многих снарядах прямой тест ps -o args= -p $$ работает, но busybox ash терпит неудачу на этом (решено).

Проверка, что $1 должно быть равно $$ удаляет большинство ложных срабатываний.

Последний ;: используются для поддержки работы Shell для ksh и zsh.

Тесты на большем количестве систем помогут, пожалуйста, оставьте комментарий, если он не работает для вас.

Не работает в оболочках типа csh.

1
user79743

Я установил $MYSHELL для будущих тестов в моем Shell-agnostic ~/.aliases:

unset MYSHELL
if [ -n "$ZSH_VERSION" ] && type zstyle >/dev/null 2>&1; then        # zsh
  MYSHELL=`command -v zsh`
Elif [ -x "$BASH" ] && shopt -q >/dev/null 2>&1; then                # bash
  MYSHELL=`command -v bash`
Elif [ -x "$Shell" ] && which setenv |grep builtin >/dev/null; then  # tcsh
  echo "DANGER: this script is likely not compatible with C shells!"
  sleep 5
  setenv MYSHELL "$Shell"
fi

# verify
if [ ! -x "$MYSHELL" ]; then
  MYSHELL=`command -v "$(ps $$ |awk 'NR == 2 { print $NF }')"`
  [ -x "$MYSHELL" ] || MYSHELL="${Shell:-/bin/sh}"  # default if verify fails
fi

Раздел tcsh, скорее всего, неразумно свернуть в сценарий в стиле POSIX, поскольку он настолько радикально отличается (таким образом, предупреждение и пауза в пять секунд). (С одной стороны, csh - оболочки стиля не могут делать 2>/dev/null или >&2, как отмечено в известном Программирование Csh считается вредным rant.)

0
Adam Katz