如果我打开一个像我这样的终端,xterm
我就会有一个外壳。然后,如果我使用ssh
或zsh
我将有另一个“级别”的外壳。有没有办法知道我需要Ctrl+D
输入多少次exit
才能退出所有这些?我的真正意图是退出除“root”shell 之外的所有内容。
了解终端多路复用器(如screen
)对解决方案有何影响也将是一件好事。
PS:请随意更改标题,我不知道这些是否正确。
答案1
事实上,您找到了正确的术语。有一个环境变量SHLVL
,所有主要的交互式 shell(bash、tcsh、zsh)在启动时都会加 1。因此,如果在 shell 内启动 shell,则SHLVL
增加 1。
然而,这并不能直接回答您的担忧,因为SHLVL
会继承终端模拟器之类的东西。例如,在我的典型配置中,$SHLVL
xterm 中的值为 2,因为级别 1 对应于运行我的 X 会话的 shell(~/.xinitrc
或~/.xsession
)。
$SHLVL
我所做的就是在提示符中显示,但前提是 shell 的父进程是另一个 shell(使用启发式方法,例如“如果其名称以sh
加上可选标点符号和数字结尾,则它是一个 shell”)。这样,在一个 shell 在另一个 shell 下运行的罕见情况下,我可以得到明显的视觉指示。
也许您更愿意检测直接在终端模拟器下运行的 shell。您可以相当准确地做到这一点:这些 shell 的父进程具有不同的控制终端,因此ps -o tty= -p$$
会ps -o tty= -p$PPID
产生不同的输出。您可以在这些 shell 中手动重置SHLVL
为 1,或者在这些 shell 中将您自己的值设置TERMSHLVL
为 1(否则递增)。
1
尽管看手册页人们不会认为它是这样的:支持它的三个 shell 的 .NET 文档中都不包含“level”一词SHLVL
。
答案2
一种(诚然不是完美的)方法是将结果添加ps --no-headers -o comm $PPID
到 shell 提示符中。这将告诉您生成 shell 的进程的名称。如果您位于嵌套的 zsh 中,它会显示“zsh”。如果您位于顶级 zsh 中,它将显示“xterm”或“screen”或您的 shell 正在运行的任何内容。
要判断您是否处于 ssh 或 su 会话中,您只需查看提示符中的主机名和用户名部分即可。
当您运行嵌套屏幕时(我认为这不是常见情况),我无法判断您是在嵌套屏幕的顶级 shell 中,还是在顶级 shell 中顶级屏幕的。您可以将屏幕配置为始终显示状态行,如果您位于嵌套屏幕中,这将导致显示多个状态行。
答案3
不是很优雅,但你可以使用树视图在顶部查看 shell 与其他正在运行的进程的父子关系。
$ htop # then press 't' and scroll around or 'Ctrl-W' to find your shell proccess
并用它来推断在到达“根”shell 之前需要退出的 shell 数量
答案4
我发现
$ pstree -u | grep ${USER}
对于了解我在系统中“适合”的位置非常有帮助。我更喜欢它pstree -u ${USER}
。
有时它会提醒我,我离开了一个nohup
正在运行的工作,或者类似的。
(另外,我使用alias grep='grep --color=auto'
。)