如何确定我正在使用的当前shell ?

仅仅ps命令的输出就足够了吗?

如何在不同风格的Unix中实现这一点?


当前回答

你可以试试:

ps | grep `echo $$` | awk '{ print $4 }'

Or:

echo $SHELL

其他回答

这个在Red Hat Linux (RHEL), macOS, BSD和一些aix上运行良好:

ps -T $$ | awk 'NR==2{print $NF}' 

或者,如果pstree可用,下面的一个也应该工作,

pstree | egrep $$ | awk 'NR==2{print $NF}'

如果你只是想确保用户正在使用Bash调用脚本:

if [ -z "$BASH" ]; then echo "Please run this script $0 with bash"; exit; fi

或参考

if [ -z "$BASH" ]; then exec bash $0 ; exit; fi

不需要从"ps"的输出中Grepping PID,因为你可以从/proc目录结构中读取任何PID的相应命令行:

echo $(cat /proc/$$/cmdline)

然而,这可能并不比简单地:

echo $0

关于运行一个与名称不同的shell,一个想法是使用之前获得的名称从shell请求版本:

<some_shell> --version

sh似乎失败的退出码2,而其他人给出一些有用的(但我无法验证所有,因为我没有他们):

$ sh --version
sh: 0: Illegal option --
echo $?
2

请使用以下命令:

ps -p $$ | tail -1 | awk '{print $4}'

如果您只是想检查您正在运行(特定版本的)Bash,最好的方法是使用$BASH_VERSINFO数组变量。作为一个(只读)数组变量,它不能在环境中设置, 因此,您可以确定它来自当前shell(如果有的话)。

但是,由于Bash在作为sh调用时具有不同的行为,因此还需要检查以/ Bash结尾的$ Bash环境变量。

在我写的一个脚本中,使用了带-(不是下划线)的函数名,并依赖于关联数组(在Bash 4中添加),我有以下完整性检查(有有用的用户错误消息):

case `eval 'echo $BASH@${BASH_VERSINFO[0]}' 2>/dev/null` in
    */bash@[456789])
        # Claims bash version 4+, check for func-names and associative arrays
        if ! eval "declare -A _ARRAY && func-name() { :; }" 2>/dev/null; then
            echo >&2 "bash $BASH_VERSION is not supported (not really bash?)"
            exit 1
        fi
        ;;
    */bash@[123])
        echo >&2 "bash $BASH_VERSION is not supported (version 4+ required)"
        exit 1
        ;;
    *)
        echo >&2 "This script requires BASH (version 4+) - not regular sh"
        echo >&2 "Re-run as \"bash $CMD\" for proper operation"
        exit 1
        ;;
esac

在第一种情况下,您可以忽略对特性的功能检查,只假设将来的Bash版本是兼容的。