如何知道我所在的贝壳的“级别”?

phu*_*ehe 35 shell terminal

如果我打开一个终端,就像xterm我会有一个外壳。然后,如果我使用sshzsh我将有另一个“级别”的外壳。有没有办法知道我必须多少次Ctrl+D或键入多少次exit才能退出所有这些?我的真正意图是退出除“root”shell 之外的所有内容。

知道终端多路复用器(如screen)对解决方案有什么影响也会很好。

PS:请随意更改标题,我不知道这些是否正确。

Gil*_*il' 43

事实上,您已经找到了正确的术语¹。有一个环境变量SHLVL,所有主要的交互式 shell(bash、tcsh、zsh)在启动时都会增加 1。所以如果你在一个 shell 中启动一个 shell,SHLVL增加 1。

但是,这并不能直接回答您的担忧,因为会SHLVL继承终端模拟器之类的东西。例如,在我的典型配置中,$SHLVL在 xterm 中为 2,因为级别 1 对应于运行我的 X 会话(~/.xinitrc~/.xsession)的 shell 。

我所做的是$SHLVL在我的提示中显示,但前提是 shell 的父进程是另一个 shell(使用启发式方法,例如“如果它的名称以sh加上可选的标点符号和数字结尾,则它是一个 shell”)。这样,在一个 shell 在另一个 shell 下运行的罕见情况下,我有一个明显的视觉指示。

也许您更喜欢检测直接在终端模拟器下运行的 shell。你可以相当准确地做到这一点:这些都是它的父进程有不同的控制终端的炮弹,使ps -o tty= -p$$ps -o tty= -p$PPID产生不同的输出。您可以SHLVL在这些 shell 中手动重置为 1,或者在这些 shell 中将您自己的值设置TERMSHLVL为 1(否则增加)。

¹ 虽然人们不会认为它查看手册页:支持它的三个外壳程序中没有一个在其SHLVL.


sep*_*p2k 7

一种(当然不是完美的)方法是将 的结果添加ps --no-headers -o comm $PPID到您的 shell 提示符中。这将告诉您生成 shell 的进程的名称。如果您在嵌套的 zsh 中,它会显示“zsh”。如果您在顶级 zsh 中,它将读取“xterm”或“screen”或您的 shell 正在运行的任何内容。

要判断您是在 ssh 还是 su 会话中,您只需查看提示符的主机名和用户名部分即可。

当您运行嵌套屏幕时(我不认为这是一种常见情况),我无法想出您是在嵌套屏幕的顶级外壳中还是在顶级外壳中的顶级屏幕。您可以将屏幕配置为始终显示一个状态行,如果您在嵌套屏幕中,这将导致显示多个状态行。

  • @phunehehe:`--option-name` 主要是特定于 GNU 的功能,因此在 Linux 之外的标准系统实用程序中大多不可用。但是你可以通过在列名后添加 `=` 来便携地获得 `ps --no-headers` 的效果。此外,`comm` 列不是 POSIX,但 `cmd` 列(包括命令的参数)是。在 POSIX 语法中,在 PID 之前也需要“-p”。因此`ps -o cmd= -p $PPID` 是可移植的并提供类似的信息。 (3认同)
  • @phunehehe:对不起,我在上面的评论中犯了一个错误。事实上,`comm` 列由 POSIX 指定并记录在 Mac OS X 上,而 `cmd` 列存在于 Linux 上但不是标准的。 (2认同)