Определите, является ли запущенная оболочка bash или zsh - PullRequest
1 голос
/ 25 марта 2020

Как я могу окончательно определить, является ли текущая работающая оболочка bash или zsh?

(возможность устранения неоднозначности между дополнительными оболочками является бонусом, но только bash & zsh 100% необходимо)

Я видел несколько способов предположительно сделать это, но у всех есть проблемы (см. Ниже).

Лучшее, что я могу придумать, - это запустить какой-нибудь синтаксис, который будет работать на одном, а не на другом, а затем проверить ошибки / выходы, чтобы увидеть, какая оболочка работает. Если это лучшее решение, какая команда будет лучшей для этого теста?

Самое простое решение будет, если каждая оболочка включает в себя параметр только для чтения с тем же именем, который идентифицирует оболочку. Однако, если это существует, я не слышал об этом.

Неопределенные способы определения работающей в данный момент оболочки:

# default shell, not current shell
basename "${SHELL}"

# current script rather than current shell
basename "${0}"

# BASH_VERSINFO could be defined in any shell, including zsh
if [ -z "${BASH_VERSINFO+x}" ]; then
    echo 'zsh'
else
    echo 'bash'
fi

# executable could have been renamed; ps isn't a builtin
shell_name="$(ps -o comm= -p $$)"
echo "${shell_name##*[[:cntrl:][:punct:][:space:]]}"

# scripts can be sourced / run by any shell regardless of shebang
# shebang parsing

Ответы [ 4 ]

0 голосов
/ 25 марта 2020

Это должно работать для большинства Linux систем:

cat /proc/$$/comm

Быстро и просто.

0 голосов
/ 25 марта 2020

Хотя не существует 100% надежного способа достижения этого, это может помочь сделать

echo $BASH_VERSION
echo $ZSH_VERSION

Обе переменные оболочки (не переменные среды), которые устанавливаются соответствующей оболочкой. В соответствующей другой оболочке они пусты.

Конечно, если кто-то специально создает переменную с таким именем или экспортирует такую ​​переменную, а затем создает подоболочку другого типа, то есть

# We are in bash here
export BASH_VERSION 
zsh  # the subshell will see BASH_VERSION even though it is zsh

этот подход потерпит неудачу; но я думаю, что если кто-то действительно так поступает, он намеренно саботирует ваш код.

0 голосов
/ 25 марта 2020

Работая на основе комментариев @ruakh & @oguzismail, я думаю, что у меня есть решение.

\shopt -u lastpipe 2> /dev/null
shell_name='bash'; : | shell_name='zsh'
0 голосов
/ 25 марта 2020

В командной строке $ выполните:

echo $0

, но вы не можете использовать $0 в скрипте, так как $0 станет самим script's name.

To найти текущую оболочку (скажем, BASH), если выполнимый номер shebang / magi c был #!/bin/bash в сценарии:

#!/bin/bash
echo "Script is: $0 running using $$ PID"
echo "Current shell used within the script is: `readlink /proc/$$/exe`"

script_shell="$(readlink /proc/$$/exe | sed "s/.*\///")"

echo -e "\nSHELL is = ${script_shell}\n" 

if [[ "${script_shell}" == "bash" ]]
then
    echo -e "\nI'm BASH\n"
fi

Выходы :

Script is: /tmp/2.sh running using 9808 PID
Current shell used within the script is: /usr/bin/bash

SHELL is = bash

I'm BASH

Это будет работать, если шебанг был: #!/bin/zsh (также).

Затем вы получите вывод для SHELL:

SHELL is = zsh
...