最终确定当前运行的shell是bash还是zsh

XDR*_*XDR 7 bash zsh

如何确定当前运行的 shell 是 bash 还是 zsh?

(能够消除其他 shell 之间的歧义是一个好处,但只有 bash 和 zsh 是 100% 必要的)

我已经看到了几种据说可以做到这一点的方法,但它们都有问题(见下文)。

我能想到的最好的方法是运行一些适用于其中一个而不是另一个的语法,然后检查错误/输出以查看哪个 shell 正在运行。如果这是最佳解决方案,那么什么命令最适合此测试?

最简单的解决方案是每个 shell 都包含一个与标识 shell 相同名称的只读参数。然而,如果存在的话,我还没有听说过。

确定当前运行的 shell 的非确定方法:

# 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
Run Code Online (Sandbox Code Playgroud)

Aru*_*gal 7

在 $ 提示符下,运行:

echo $0
Run Code Online (Sandbox Code Playgroud)

但您不能$0在脚本中使用,因为$0它将成为脚本script's name本身。

如果 shebang / magic number 可执行文件位于脚本,则要查找当前 shell(假设为 BASH) :#!/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
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

#!/bin/zsh如果 shebang 是:(也),那么这将起作用。

然后,您将获得 SHELL 的输出:

SHELL is = zsh
Run Code Online (Sandbox Code Playgroud)


use*_*428 5

虽然没有 100% 万无一失的方法来实现这一目标,但这样做可能会有所帮助

echo $BASH_VERSINFO
echo $ZSH_VERSION
Run Code Online (Sandbox Code Playgroud)

两者都是 shell 变量(不是环境变量),由各自的 shell 设置。在各自的另一个外壳中,它们是空的。

当然,如果有人故意创建一个这个名称的变量,或者导出这样一个变量,然后创建一个不同类型的子shell,即

# We are in a non-bash here (ksh, zsh, dash, ...)
export BASH_VERSINFO=5
zsh  # the new zah subshell will see BASH_VERSION even though it is zsh
Run Code Online (Sandbox Code Playgroud)

这种方法将会失败;但我认为如果有人真的在做这样的事情,他想故意破坏你的代码。


XDR*_*XDR 0

根据@ruakh 和@oguzismail 的评论,我想我有一个解决方案。

\shopt -u lastpipe 2> /dev/null
shell_name='bash'; : | shell_name='zsh'
Run Code Online (Sandbox Code Playgroud)