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

69

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

user5837
источник
2
@xenoterracide: по крайней мере unix.stackexchange.com/questions/3645/… . Ответ geekosaur является более полным, поэтому я проголосовал за закрытие предыдущего вопроса.
«SO- перестать быть злым» Жиля
1
эхо $ SHELL, нет?
мир невинных
@ innocent-world Нет, echo #SHELLне совсем так. Смотрите # 3 в Ответе geekosaur .
Василий Бурк
Я не уверен, что «оболочка» имеет четко определенный смысл. Например, вы можете запустить, xterm -e /bin/cat но я не рад вызывать /bin/catоболочку.
Старынкевич
Также некоторые оболочки (например, scsh ) не используют оболочку POSIX, как синтаксис.
Старынкевич,

Ответы:

71

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

  1. ps -p$$ -ocmd=, (В Solaris это может потребоваться fnameвместо cmd. В OSX и BSD должно быть commandвместо cmd.)
  2. Проверьте $BASH_VERSION, $ZSH_VERSIONи другие переменные оболочки специфические.
  3. Проверить $SHELL; это последнее средство, так как оно определяет оболочку по умолчанию, а не обязательно текущую оболочку.
geekosaur
источник
4
Вы $0тоже должны упомянуть ?
Микель
Мне не нравится, $0потому что это более сложно: (1) это может быть просто базовое имя, (2) оно может иметь «-» на передней панели, чтобы обозначить его как оболочку входа в систему.
geekosaur
ps -p$$ -ocmd=""красивее :-)
asoundmove
1
@geekosaur: может быть и так, но $0все же кажется более полезным, чем $SHELL: вы не согласны? Вы всегда можете пропустить это, sedчтобы удалить «-».
иконоборчество
2
Если вы работаете tcsh, $tcshи $versionбудет установлено. Это переменные оболочки, а не переменные среды. Если вы используете не-tcsh версию csh, я не думаю, что есть какие-либо отличительные переменные. И, конечно же, синтаксис, используемый для проверки переменных, отличается между csh / tcsh с одной стороны и sh / ksh / bash / zsh с другой.
Кит Томпсон
41

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

$ ps -p $$

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

$ echo $0
Стивен Д
источник
2
Также не работает на рыбе.
Ron E
Я думаю, что ответ @ jiliagre, вероятно, я бы использовал сегодня. На рыбе %selfможно использовать вместо$$
Стивен Д.
8

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

$ ps -o comm= -p $$
ksh93 
jlliagre
источник
6

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

palswim
источник
7
ps | grep $$может по-прежнему давать ложные срабатывания, если, например, ваш текущий процесс 1234и есть процесс 12345.
Кит Томпсон
4

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

  • Используя команду 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)

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

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

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

Дэвид Гойтия
источник
3

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

ps -p$$ -o cmd="",comm="",fname="" 2>/dev/null | sed 's/^-//' | grep -oE '\w+' | head -n1
Себастьен
источник
это дает мне мое текущее имя каталога; Кроме того, под, cshи tcshэто дает мнеAmbiguous output redirect.
иконоборца
2

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

echo $SHELL
jasonleonhard
источник
Это, скорее всего, вернет путь к исполняемому файлу оболочки вашей оболочки входа в систему. Хотя вы не уверены, что оболочка для входа - это то, что вы сейчас используете.
Кусалананда
1

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

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

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

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

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

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

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

Не работает в cshтипе снарядов.


источник
В OS / X в моих тестах я получил как минимум 3 строки: одну для оболочки, одну для /usr/lib/dyld, одну для /private/var/db/dyld/dyld_shared_cache_x86_64.
Стефан Шазелас
Да, теперь он только выбирает записи в / bin и / usr / bin
Стефан Шазелас
@ StéphaneChazelas Может, сейчас лучше?
0

Я настроен $MYSHELLна будущие тесты в моей оболочке-агностике ~/.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 Programming считается вредными .)

Адам Кац
источник
-1

Вы можете просто использовать echo $0команду, чтобы проверить, какую оболочку вы используете, и <name_of_the_shell> --versionпроверить версию оболочки. (например. bash --version)

Сачин С
источник
Стивен D уже упоминал об этом
:)