如何判断我是否在屏幕上?


77

在Linux中使用屏幕时,如何确定我是否在屏幕中?如果可以exit,我可以退出屏幕,但是如果没有,那么我将关闭终端。

在执行操作时screen -r,我可以查看是否还连接了其他屏幕,但是如何知道我的当前终端是否是这些已连接屏幕之一?


值得一提的是,如果您在屏幕上并运行screen -r,它会通知您您在屏幕上(或者,如果没有屏幕,则告诉您您可能不在其中),以及不在屏幕上并固定在屏幕上,您只需键入C-a(或任何屏幕命令键)+d即可退出刚输入的屏幕。因此,这是一种简单的说法。但是,不值得给出答案,因为我假设OP已经知道/取消了该选项。
Parthian Shot

Answers:


128

检查$STY。如果为空,则您位于“真实”终端上。如果包含任何内容,则为您所在屏幕的名称。

如果您不在屏幕上:

eric@dev ~ $ echo $STY
eric@dev ~ $ 

如果您在屏幕上:

eric@dev ~ $ echo $STY
2026.pts-0.ip-10-0-1-71

4
STY代表什么?
史蒂文·你

2
@StevenYou我所发现的只是“备用套接字名称”。这并不能真正解释变量名的选择。
ahruss

1
如果您与启动屏幕的机器位于同一台计算机上,则此方法有效。如果ssh切换到新计算机,则需要传递变量。(即ssh user @ host“ STY = $ STY”)
Aaron Oommen 2015年

8
@StevenYou可能代表“ Screen TYpewriter”或“ Socket TYpewriter”。TTY代表“ TeleTYpewriter”,PTY代表“伪终端TYpewriter”。他们可能认为这很明显,因此无需明确提及其推理。正如这次谈话所证明的,他们错了。
Parthian Shot

3
对于它的价值,这似乎不适用于osx上的tmux,而基于“ $ TERM”的检查却可以。
AndreiBârsan2015年

16

我做过的另一种方法是回显$ TERM。

 $ echo $TERM
 screen

由于我最终要做很多,因此我在.bashrc文件中添加了一个别名:

alias trm='echo $TERM'

这样,无论是否在屏幕上,如果我只执行“ trm”,它将显示我是否在SCREEN或其他位置(通常是XTERM)。


为了明确起见,在Linux下,$ TERM的值将screen.linux在屏幕会话中。
Parthian Shot

令人高兴的是,tmux下的$ TERM值是“ screen”(至少在OS X上是)
Michael

1
实际上,至少在所有最新的OS-X / macOS,所有最新的CentOS和Ubuntu(至少14.04)中,Parthian的$ TERM都只会返回“屏幕”。不知道在哪个版本的OS /内核/ shell下看到“ screen.linux”。
JJC

13

检查您是否在屏幕上的另一种方法。

类型:

Ctrl-a ?

如果看到屏幕帮助,则说明您在屏幕上。

否则,您会得到一个问号“?” 在提示符下。


1
当然,这假定Ctrl+a是屏幕的命令字符。尽管对大多数人来说这是正确的,但值得指出的是,命令字符可以被-e标志覆盖,因此这并不总是有效的。
Parthian Shot

这很好用(例如,Ctrl + a然后“转义”)。虽然我想如果您不在屏幕上,它可能会将光标移到当前行的开头...:|
rogerdpack

2

由于此处的所有其他方法都依赖于环境变量(可以被简单地覆盖)或屏幕的命令字符(也可以被覆盖),因此最安全的检查方法是列出当前进程的所有祖先。

pstree --show-parents -p $$ | head -n 1 | sed 's/\(.*\)+.*/\1/' | grep screen | wc -l

如果输出为1,则您正在运行的当前进程的祖先在可执行文件的名称中带有“ screen”一词,否则就没有。

可以从以下位置获得更方便的可见检查:

pstree --show-parents -p $$ | head -n 1 | sed 's/\(.*\)+.*/\1/' | less

1
有趣的方法。但是,您都不需要-phead -n 1 | sed 's/\(.*\)+.*/\1/'并且wc -l我建议在grep中添加-w以便安全(它只会匹配名为“ screen”而不是“ screenish”的程序)。所以这是最终命令pstree --show-parents $$|grep -w screen。但是,如果有人弄乱了您的环境变量,那么他也可能弄乱了可执行文件的名称:)
ndemou

1

在ssh进入远程(较旧)系统时,我注意到$ TERM表示我正在使用“ screen-256color”,但是由于没有termcap / terminfo条目,因此我被迫诉诸.bashrc中的以下内容:防止终端产生偶尔的垃圾:

case $TERM in 
    (screen-256color) export TERM='screen'
esac

使其使用普通条目代替。

TL; DR,$ TERM通常会在远程ssh时指示您是否处于屏幕会话中。case $TERM in (screen*) echo "you are in a screen session"; esac如果您只需要视觉提示并且不需要做特定的事情,就可以使用


1

将以下一项或多项添加到您的 .bashrc

  • alias mysession='echo ${STY}'
  • alias myterm='echo ${TERM}'
  • alias isscreen='if test -n "$STY"; then echo " screen session: ${STY}"; else echo " NOT a screen session"; fi'

然后,您可以screen通过键入简单的命令来知道自己是否在其中。


1
此方法的一种变体是将${TERM}您的提示添加到中$PS1。这也可以在您的计算机中完成.bashrc。例如,如果您$PS1将设置为[\u@\h \W]\$,则可以使用export PS1="[\u@\h ${TERM} \W]\$"
Rhubbarb

我现在做这样的事情,除了一点点幻想。:)。当$ TERM =='screen'时,我在提示处添加了明亮的“ S”。无需输入任何内容即可轻松知道自己是否在其中。我将如何做作为练习留给读者。
JJC

1

我对这个问题的解决方案要简单得多:如果您位于GNU Screen内,只需单击一下即可 TAB使整个终端闪烁(快速的视频倒置)。

经测试可在大多数Linux(Ubuntu,Kali,Debian,RaspBerry等)和FreeBSD,GUI以及任何本地或远程终端(包括远程终端)上运行CtrlAltFn

作为此方法的例外,请注意这种(相当复杂,但可能的)情况:

  • 1.- SSH进入计算机A(假设为Linux)。
  • 2.-screen -S AScr从计算机A上的远程终端输入新的。
  • 3.-从GNU ScreenAScr终端到计算机B的SSH 。
  • 4.-screen -S BScr从计算机B上的远程终端输入新的。

Screen在案例2和4的内部,而Screen在案例1和3的外部,但是终端将在案例2、3和4上闪烁。


0

上述大多数答案的问题在于,我们可能位于附加的屏幕会话的子外壳中。或者我们可能正在通过屏幕会话在远程主机上打开外壳。在前一种情况下,我们可以遍历进程树的父关系并匹配screen程序名称。在后一种情况下,大多数时候,我们可以检查TERM变量中类似的内容screen*

我的答案与/ u / Parthian-Shot类似,但并不完全取决于pstree实用程序;他使用的选项对我不可用。另一方面,我的实现仍然依赖于Linux:对于非Linux系统,必须调整ps命令。对于具有不支持阵列的较旧外壳的系统,您将有更多解决方法。但无论如何:

ps_walk_parents() {
  local tmp
  local ppid=$PPID
  while [[ $ppid != 1 ]]; do
    tmp=($( ps -o ppid,comm -p $ppid ))
    ppid=${tmp[0]}  # grab parent pid
    echo ${tmp[1]}  # output corresponding command name
  done
}
if [[ "$TERM" =~ screen* ]] || ps_walk_parents |grep -qxi screen ; then
  # we are in a screen terminal 
fi

我们可以对函数进行一些优化,以在进程父项与目标命令名称(“屏幕”)匹配时停止搜索,但是通常,该函数只会执行2到3次迭代。大概您想将此代码放入一些启动初始化中,例如.bashrc或.profile或其他内容,因此同样,不值得优化。


据我所知,如果我们位于附加屏幕会话的子外壳中,而其中不保留$ TERM和$ STY,则您的方法很有用。您能举一个例子说明这种情况如何发生的原因,因为无论我尝试执行什么操作,$ TERM和$ STY始终被保留。
ndemou

它们在启动时被保留,但是如果您放到一个子shell中,则不必保留(Try env -i bash)。或者,如果您连接的终端实际上​​是通过附加到其他主机的,ssh而TERM变量在其他主机的bashrc中被覆盖。
Otheus

-3

screen -ls 能告诉你。

外屏:

$ screen -ls
There are screens on:
        16954.pts-1.auds916     (Detached)
        242.pts-8.auds916       (Detached)
2 Sockets in /tmp/screens/S-glennj.

屏幕内:

$ screen -ls
There are screens on:
        16954.pts-1.auds916     (Attached)
        242.pts-8.auds916       (Detached)
2 Sockets in /tmp/screens/S-glennj.

7
并不是的。仅因为屏幕已连接并不意味着您在其中。它也可能从另一个终端连接/打开。
andol 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.