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

Я хотел бы знать, работает ли данный скрипт под Ash, Dash, Bash, ZSH или чем-то еще.

Сценарий может иметь или не иметь строку shebang, и он может выполняться либо напрямую (my-script.sh), либо как аргумент интерпретатору оболочки (sh my-script.sh).

Какой самый простой способ узнать это?

Изменить: после прочтения приведенных ниже ответов и повторяющегося вопроса я обнаружил, что это самый простой и надежный способ найти имя оболочки, выполняющей скрипт под Linux:

show_shell() { basename "$(readlink -f /proc/$$/exe)" ;}

person Elifarley    schedule 13.06.2016    source источник
comment
Как этот скрипт вызывается? Есть ли в сценарии #!' линия?   -  person Kenster    schedule 13.06.2016
comment
Отредактировано, чтобы уточнить это.   -  person Elifarley    schedule 13.06.2016
comment
Возможный дубликат Как определить текущую оболочку, над которой я работаю ?   -  person Thomas Dickey    schedule 14.06.2016


Ответы (1)


Не существует универсального стандартного способа получить имя, которое идентифицирует текущая оболочка.

Раковины Prouder оставляют маркеры, которые вы можете проверить:

[ "$BASH_VERSION" ] && echo bash
[ "$ZSH_VERSION" ] && echo zsh
[ "$KSH_VERSION" ] && echo ksh

Более скромные оболочки, такие как ash и dash, этого не делают.

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


Если (и только если) вы работаете в Linux, возможно, вы сможете почерпнуть некоторые идеи из /proc/$$/exe:

$ dash -c 'ls -l /proc/$$/exe'
lrwxrwxrwx 1 me me 0 Jun 13 11:46 /proc/10933/exe -> /bin/dash

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

person that other guy    schedule 13.06.2016
comment
Ваш пример с использованием $$ работает для Dash, но для Bash и ZSH печатается путь к внутренней команде (ls): bash -c 'ls -l /proc/$$/exe' /proc/3576/exe -> /bin/ls - person Elifarley; 13.06.2016
comment
@Elifarley Хороший вопрос. Это связано с тем, что bash/zsh умен, когда нужно выполнить только одну команду. Если вы используете это как часть скрипта (или добавляете фиктивный ; true), он будет отображаться правильно. - person that other guy; 13.06.2016
comment
Поэтому я бы объявил такую ​​функцию: show_shell() { readlink -f /proc/$$/exe ;} - person Elifarley; 13.06.2016
comment
В стороне: еще один важный объект, на который следует обратить внимание, — это рыба, которая гордится этой таксономией. shell [ "$FISH_VERSION" ] && echo fish` - person dan mackinlay; 21.11.2019