找出什么是sh

the*_*en8 3 shell version environment-variables

我写了一组脚本,我想成为便携式的,但我需要知道是否sh在当前平台上表示bashkshash。有明确的方法吗?

我首先想到的是检查哪个外壳具有哪个--version

$ zsh --version
zsh 5.0.2 (x86_64-apple-darwin13.0)

$ bash --version
GNU bash, version 4.3.39(1)-release (x86_64-apple-darwin13.4.0)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

$ ksh --version
  version         sh (AT&T Research) 93u+ 2012-08-01

$ dash --version
dash: 0: Illegal option --

$ pdksh --version
pdksh: pdksh: --: unknown option
Run Code Online (Sandbox Code Playgroud)

除了笨拙之外,这甚至不会在所有情况下都产生结果。

编辑

我的bashrc / zshrc / ...类项目需要它,我将当前工作的 shell 分配给一个变量,并在任何地方使用该变量。

我无法发布我的代码,因为我需要解决问题才能使我的工作保持整体清洁。此外,它会是太多的猴子代码......不要误解它,但是 POSIX 兼容性太窄,无法使我的项目足够小。否则我需要依靠系统配置。

但是,我可以发布我的 UNIX Shell 定义函数:

PROJ_GET_SHELL () {
    local PROJ_SHELL="`ps -p $$ | tail -1 | tr ' ' '\n' | tail -1`"
    PROJ_local=(pdksh bash dash mksh zsh ksh sh)
    for i in ${PROJ_local[*]}
    do
        if ! [ -z `echo $PROJ_SHELL | grep $i` ]
        then
            echo "$i"
            break
        fi
    done
}
Run Code Online (Sandbox Code Playgroud)

附注。最起码的研究表明 $SHELL 在将 shell 作为子进程运行时不会改变。

Dan*_*der 5

在流行的发行版上:

$ which sh
/bin/sh
$ readlink -f /bin/sh
/bin/dash
Run Code Online (Sandbox Code Playgroud)

或更紧凑:

$ readlink -f $(which sh)
/bin/dash
Run Code Online (Sandbox Code Playgroud)

但是,某些(尤其是嵌入式系统或 initrd 版本)将其 shell 直接编译为 /bin/sh 或者它是硬链接(busybox)

另一个不寻常的情况是 Windows。git bash 在这种情况下:

$ readlink -f $(which sh)
/usr/bin/sh
Run Code Online (Sandbox Code Playgroud)