如何检查我使用的是哪个 shell?

Lea*_*969 538 command-line

我读到终端只不过是 shell,而 Unix 提供了不同风格的 shell:

  • 伯恩壳 (sh)
  • C 壳 (csh)
  • TC 外壳 (tcsh)
  • 科恩壳 (ksh)
  • Bourne Again shell (bash)

问题:

  • 当我打开终端窗口时,默认打开的是哪个 shell?
  • 如何查看安装了多少个shell?
  • 如何更改我帐户中使用的外壳?

kin*_*ilo 621

您可以在终端中键入以下命令以查看您使用的是哪个 shell:

echo $0
Run Code Online (Sandbox Code Playgroud)

如果您使用bash ( Bourne Again Shell ) 终端,结果将类似于以下内容:

-bash
Run Code Online (Sandbox Code Playgroud)

  • @Mi_Onim $0 是正在运行的进程的名称。如果您在 shell 中使用它,那么它将返回 shell 的名称。如果您在脚本中使用它,它将是脚本的名称。 (60认同)
  • @Anwar 提出了一个很好的观点,在您从 `echo $0` 获得 shell 名称后,`ls -l `which <name>` `` 以查看它是否符号链接到另一个 shell 二进制文件。 (13认同)
  • `0` 是环境变量吗? (10认同)
  • 如果是符号链接,则不起作用。像“bash”一样“sh” (5认同)
  • **注意**:这不适用于交互式 `csh`。`% echo $0 没有 $0 的文件。`,但它确实适用于 `tcsh` (2认同)
  • 不适用于 `su - user` (2认同)
  • 这是一个糟糕的解决方案。可以通过多种方式更改程序的名称。 (2认同)
  • 不适用于鱼壳 (2认同)

hee*_*ayl 170

要查找默认环境中的 shell,您可以检查SHELL环境变量的值:

echo $SHELL
Run Code Online (Sandbox Code Playgroud)

要查找当前 shell 实例,请查找具有当前 shell 实例的 PID 的进程(shell)。

要查找当前 shell 实例的 PID:

echo "$$"
Run Code Online (Sandbox Code Playgroud)

现在找到具有PID的进程:

ps -p <PID>
Run Code Online (Sandbox Code Playgroud)

把它放在一起:

ps -p "$$"
Run Code Online (Sandbox Code Playgroud)

  • $SHELL 是系统(或用户)的默认 shell,通常(但不一定)是在任何给定时刻实际使用的 shell。 (39认同)
  • `echo $SHELL` 给了我 `/bin/csh` 和 `ps -p $$` 给了我 `22673 pts/1 00:00:00 bash`。Kingmilo 解释了(上面)为什么它们不一样。 (3认同)
  • 要以在 gnu 和 bsd ps 版本之间移植的方式仅获取当前 shell 的 shell 名称,这很有效:`ps -cp "$$" -o command=""` (2认同)

the*_*wla 42

$SHELL为您提供默认外壳。 $0给你当前的外壳。

例如:我将 bash 作为我的默认 shell,用于我的终端应用程序。但是对于我的 iTerm2 应用程序,我在窗口打开时使用命令:/bin/ksh.

所以我 $0给了我/bin/kshiTerm2。 $SHELL给我/bin/bashiTerm2。 $0,在终端上$SHELL给我/bin/bash

  • 这是对其他最高投票答案的很好的消歧。谢谢你。 (2认同)
  • 您不想继续以这种方式来回移动,因为您将 shell 堆叠在 shell 中,并且每个 shell 中都有一个新的上下文。一般来说,最好输入 ctrl-d 或 exit 以返回到先前的 shell。 (2认同)

Eva*_*enn 18

其他答案往往使用特定于 shell 的功能,但我们试图发现我们使用的是哪个 shell,因此他们假设了问题的答案。例如,没有一个答案适用于鱼。

sh -c 'ps -p $$ -o ppid=' | xargs ps -o comm= -p
Run Code Online (Sandbox Code Playgroud)

而是在调用 sh 时使用 $$ 语法,但是我们正在寻找 PPID 而不是 PID。使用 PPID 查找 cmd。

sh -c 'ps -p $$ -o ppid=' | xargs -I'{}' readlink -f '/proc/{}/exe'
Run Code Online (Sandbox Code Playgroud)

感谢改进@muru

  • 您可以使用 `ppid=`/`cmd=` 来省略标题(以及 `tail -1`s),并考虑查看 `/proc/.../exe` 以查看正在运行的文件(因为 cmd 输出可以被任何运行 shell 的人操作)。 (2认同)
  • 显然这在busybox中不起作用,因为不符合posix:参考:https://github.com/broadinstitute/cromwell/pull/3561#pullrequestreview-116186537 (2认同)

kos*_*kos 10

要知道哪个是您的用户的默认 shell,您可以运行:

echo "$SHELL"
Run Code Online (Sandbox Code Playgroud)

例如,如果您使用 Bash,您应该得到以下输出:

/bin/bash
Run Code Online (Sandbox Code Playgroud)

如果您没有更改任何配置,它应该是 Bash,因为 Bash 是 Ubuntu 上的默认 shell。

  • @frederickjh 鱼在这里有点奇怪。`$$` 变量实际上是 [由 POSIX 定义的](http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_05_02) 并且适用于绝大多数 shell。Fish 决定不遵循这里的标准,所以我认为忽略它是公平的。我可以确认 `$$` 在 sh、dash、bash、zsh、ksh、ash、tcsh 和 csh 中按预期工作。事实上,除了不能工作的鱼之外,我想不出任何其他贝壳。 (2认同)

小智 10

原帖问了三个问题。给出的答案确实涵盖了第一个问题,“当我打开终端窗口时,默认情况下打开哪个 shell?” 他们还回答了一个没有被问到的问题,即“如何找出当前在终端中运行的 shell?” 但是,据我所知,没有人回答最初提出的第二个问题或第三个问题,即“如何检查安装了多少个外壳?” 和“如何更改我帐户中使用的外壳?”

  • 回答“如何检查安装了多少个 shell?” 以下命令将列出所有可用的 shell:

    cat /etc/shells
    
    Run Code Online (Sandbox Code Playgroud)

    例如,在 Ubuntu 18.10 的默认安装中,这给出:

    # /etc/shells: valid login shells
    /bin/sh
    /bin/dash 
    /bin/bash
    /bin/rbash
    
    Run Code Online (Sandbox Code Playgroud)

    但是,默认情况下 sh 是指向破折号的符号链接,而 rbash 使用选项 -r(“受限 bash”)链接到 bash,因此实际上只有两个 shell,而不是上面列表中建议的四个。以下命令将显示列出的任何 shell 是否实际上是符号链接,如果是,它们链接到哪里: ls -l /bin

  • 现在是“如何更改我帐户中使用的 shell?”的问题。假设这意味着“我如何永久地改变默认的shell,一个终端将使用”,有一个答案在这里


Mik*_*ton 5

您可能不想知道当前 shell 的名称(例如-bash,来自),也不想知道默认 shell 的可执行路径(来自),而是想知道当前 shell 的可执行路径bash(特别有用,例如,如果您有多个版本的 Bash安装)。zshecho $0echo $SHELL

为此,您可以使用lsof -p "$$"或 一些额外的编码来提取所需的信息:

lsof -p "$$" | grep -m 1 txt | xargs -n 1 | tail -n 1
Run Code Online (Sandbox Code Playgroud)

通过 Homebrew 安装的 Bash 的输出示例:

/usr/local/Cellar/bash/5.1.8/bin/bash
Run Code Online (Sandbox Code Playgroud)

或者对于 Zsh:

/bin/zsh
Run Code Online (Sandbox Code Playgroud)

上面的内容与 不同echo $SHELL,既因为上面的内容适用于当前正在运行的 shell,而不是用户的默认 shell,还因为上面的内容在扩展任何符号链接后给出了可执行文件。例如,对于与上面相同的 Bash 安装,echo $SHELL给出/usr/local/bin/bash.

编辑 1:如果您需要在 shell 路径中允许可能存在空格字符,请lsof -p "$$" | grep -m 1 txt | xargs -n 1 | tail -n +9 | xargs改用。

编辑2:查看当前 shell 可执行文件的另一种方法,这次不使用lsof, 是ls -l "/proc/$$/exe"

将其转换为不需要lsof、允许 shell 可执行路径中可能存在空格并允许可能的别名的命令ls,我们得到:

"$(which ls)" -l "/proc/$$/exe" | xargs -n 1 | tail -n +11 | xargs
Run Code Online (Sandbox Code Playgroud)

请注意,最后一个版本/proc/$$不能在 macOS 上运行,而版本可以lsof在任何已安装的 Linux 上运行lsof