Answers:
一种(公认不完美)的方法是将的结果添加ps --no-headers -o comm $PPID
到您的shell提示符中。这将告诉您产生外壳程序的进程的名称。如果您在嵌套的zsh中,它将显示“ zsh”。如果您在顶级zsh中,它将显示为“ xterm”或“ screen”或您的shell正在运行的任何内容。
要确定您是在ssh会话中还是在su会话中,只需查看提示中的主机名和用户名部分即可。
当您运行嵌套屏幕时(我不认为这是常见的情况),我无法想到告诉您是处于嵌套屏幕的顶级外壳还是顶级外壳中顶级屏幕的 您可以将屏幕配置为始终显示状态行,如果您位于嵌套屏幕中,则会导致显示多个状态行。
ps: illegal option -- -
,知道为什么吗?我很快将在Linux中再次对其进行测试:)
--option-name
主要是特定于GNU的功能,因此在Linux之外的标准系统实用程序中几乎不可用。但是您可以ps --no-headers
通过=
在列名称后面添加来获得可移植的效果。同样,该comm
列不是POSIX,但是该cmd
列(包括命令的参数)是。-p
POSIX语法中的PID之前也有必要。因此ps -o cmd= -p $PPID
是便携式的,并提供类似的信息。
comm
列是由POSIX指定的,并记录在Mac OS X上,而该cmd
列存在于Linux上,但不是标准列。
实际上,您碰到了正确的词¹。有一个环境变量SHLVL
,所有主要的交互式shell(bash,tcsh,zsh)在启动时都会增加1。因此,如果您在壳内启动壳,请SHLVL
增加1。
但是,这并不能直接解决您的问题,因为会SHLVL
继承终端仿真器之类的东西。例如,在我的典型配置中,$SHLVL
xterm中的值为2,因为级别1对应于运行我的X会话(~/.xinitrc
或~/.xsession
)的外壳。
我要做的是$SHLVL
在提示符下显示,但仅在shell的父进程是另一个shell时(具有启发式的提示,例如“如果其名称结尾sh
加上可选的标点符号和数字,则是shell”)。这样,在不常见的情况下,一个外壳在另一个外壳下运行,我有明显的视觉指示。
也许您希望检测直接在终端仿真器下运行的shell。你可以相当准确地做到这一点:这些都是它的父进程有不同的控制终端的炮弹,使ps -o tty= -p$$
和ps -o tty= -p$PPID
产生不同的输出。您可以SHLVL
在这些shell中手动将其重置为1,或者在这些shell中将您自己的重置为1 TERMSHLVL
(否则增加)。
¹
虽然不会在手册页上看到它:支持它的三个shell都没有在其文档中包含“ level”一词SHLVL
。
ps -o tty= -p$pid
,这将显示进程的控制终端,它标识了该进程正在运行的终端仿真器(xterm,screen,sshd等)。启动一个新的终端模拟器。如果终端模拟器是本机Mac应用程序,则可能是我不知道的Mac特定的细节。
ps -o tty= -p$$
和ps -o tty= -p$PPID
,因为您说过它们应该产生不同的输出。还是我误会了什么?
ps -p $$ -p $PPID
(同样,我没有OSX经验,因此OSX上可能发生了异常情况)。
ps -p $$ -p $PPID
给出(抱歉,我不知道如何格式化注释)PID TTY TIME CMD 209 ttys000 0:00.01 login -pf phunehehe 210 ttys000 0:00.12 -bash