it-swarm.cn

如何测试终端中使用的Shell?

如何检查终端中使用的Shell?我在MacOS中使用的Shell是什么?

73
user5837

从最可靠到最不可靠(以及最不重要)的几种方法:

  1. ps -p$$ -ocmd=。 (在Solaris上,这可能需要是fname而不是cmd。在OSX和BSD上应该是command而不是cmd。)
  2. 检查 $BASH_VERSION$ZSH_VERSION和其他特定于Shell的变量。
  3. 检查$Shell;这是不得已的方法,因为它指定了默认 Shell,而不一定指定当前 Shell。
75
geekosaur

我发现以下内容适用于我在系统上安装的四个shell(bash,dash,zsh,csh):

$ ps -p $$

以下内容适用于zsh,bash和破折号,但不适用于csh:

$ echo $0
43
Steven D

由于该问题询问使用的Shell,并且没有讨论传递给它的潜在参数,因此可以避免显示这些参数:

$ ps -o comm= -p $$
ksh93 
8
jlliagre

关于一些较轻便的实现(Android手机,busybox等)的说明:ps并不总是支持-p开关,但是您可以使用ps | grep "^$$ "。 (此grep正则表达式将唯一标识PID,因此不会出现误报。

6
palswim

有两种非常简单的方法:

  • 使用 ps 命令:

    ps -o comm= $$
    

    要么

    ps -h -o comm -p $$
    

    哪里:

    • -h或用=结束所有选项,以不显示任何标题。
    • -o comm仅显示进程基本名称(bash而不是/bin/bash)。
    • -p <PID>仅处理提供的PID表单列表。
  • 使用 / proc 进程信息伪文件系统:

    cat /proc/$$/comm
    

    此选项的行为与上面的ps命令完全相同。

    要么

    readlink /proc/$$/exe
    

    /proc/PID/exe链接到正在执行的文件,在这种情况下,该文件将指向/ bin/bash,/ bin/ksh等。

    仅获取Shell的名称,您可以使用

    basename $(readlink /proc/$$/exe)
    

    这是唯一的选项,即使您位于脚本,源代码或终端中,也始终会得到与使用中的Shell解释器二进制文件链接相同的结果。

    警告您必须注意,这将显示最终二进制文件,因此ksh可能链接到ksh93或sh链接到bash。

/proc的用法非常有用,它通过/proc/self链接到当前命令的PID。

5
David Goitia

与Mac(comm),Solaris(fname)和Linux(cmd)兼容的所有其他答案:

ps -p$$ -o cmd="",comm="",fname="" 2>/dev/null | sed 's/^-//' | grep -oE '\w+' | head -n1
3
sebastien

如果将其保存在环境变量中,则可以使用以下命令:

echo $Shell
2
jasonleonhard

运行中的Shell的pid由var $$给出(在大多数Shell中)。

whichsh="`ps -o pid,args| awk '$1=='"$$"'{print $2}'`"
echo "$whichsh"

使用反引号使jsh(Heirlomm Shell)工作。

在许多壳中,直接测试ps -o args= -p $$有效,但busybox ash对此失败(已解决)。

支票$1必须等于$$删除大多数误报。

最后 ;:用于使Shell在ksh和zsh上运行。

在更多系统上进行测试会有所帮助,如果对您不起作用,请发表评论。

csh类型的shell中不起作用。

1
user79743

我设置 $MYSHELL用于与我的Shell无关的~/.aliases

unset MYSHELL
if [ -n "$ZSH_VERSION" ] && type zstyle >/dev/null 2>&1; then        # zsh
  MYSHELL=`command -v zsh`
Elif [ -x "$BASH" ] && shopt -q >/dev/null 2>&1; then                # bash
  MYSHELL=`command -v bash`
Elif [ -x "$Shell" ] && which setenv |grep builtin >/dev/null; then  # tcsh
  echo "DANGER: this script is likely not compatible with C shells!"
  sleep 5
  setenv MYSHELL "$Shell"
fi

# verify
if [ ! -x "$MYSHELL" ]; then
  MYSHELL=`command -v "$(ps $$ |awk 'NR == 2 { print $NF }')"`
  [ -x "$MYSHELL" ] || MYSHELL="${Shell:-/bin/sh}"  # default if verify fails
fi

tcsh部分可能不明智地放入POSIX样式的脚本中,因为它是如此不同(因此警告和五秒钟的暂停)。 (例如,csh样式的外壳不能2>/dev/null 要么 >&2,如著名的 Csh编程被认为有害 rant中所述。

0
Adam Katz