【问题标题】:How can I tell whether I'm in a screen?如何判断我是否在屏幕中?
【发布时间】:2011-03-22 14:13:38
【问题描述】:

在 linux 中使用 screen 时,如何判断我是否在屏幕中? 我可以做exit,如果我在一个屏幕中,我会退出一个屏幕,但如果我不在,那么我最终会关闭我的终端。

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

【问题讨论】:

  • 值得注意的是,如果您在屏幕中并运行screen -r,它将通知您您在屏幕中(或者,如果没有屏幕,则让您知道您可以'不可能在一个屏幕中),如果您不在屏幕中,并且与一个屏幕相连,您只需输入C-a(或任何您的屏幕命令键)+d即可退出您刚刚的屏幕进入。所以,这是一种简单的判断方法。不过,不值得给出答案,因为我假设 OP 已经知道/驳回了该选项。

标签: linux shell gnu-screen


【解决方案1】:

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

如果您不在屏幕中:

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

如果你在屏幕上:

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

【讨论】:

  • STY 代表什么?
  • @StevenYou 我只找到"alternate socket name"。这并不能真正解释变量名的选择。
  • 如果您在启动屏幕的同一台机器上,这将有效。如果你 ssh 到一台新机器,你将需要传递变量。 (即 ssh user@host "STY=$STY")
  • @StevenYou 可能代表“屏幕打字机”或“套接字打字机”。 TTY 代表“TeleTYpewriter”,PTY 代表“伪终端打字机”。他们可能认为这很明显,他们不需要明确提及他们的推理。正如这次谈话所证明的那样,他们错了。
  • 对于它的价值,这似乎不适用于 osx 上的 tmux,而基于“$TERM”的检查可以。
【解决方案2】:

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

 $ echo $TERM
 screen

因为我经常这样做,所以我在我的 .bashrc 文件中添加了一个别名:

alias trm='echo $TERM'

这样,无论是否在屏幕上,如果我只是执行 'trm',它就会告诉我我是在屏幕上还是在其他地方(通常是 XTERM)。

【讨论】:

  • 澄清一下,在 Linux 下,在屏幕会话中 $TERM 的值将是 screen.linux。
  • 幸运的是,tmux 下 $TERM 的值是“screen”(至少在 OS X 上)
  • 实际上,Parthian,至少在所有最近的 OS-X/macOS、所有最近的 CentOS 和 Ubuntu(至少 14.04)中,$TERM 确实只返回“屏幕”。不确定您在哪个版本的 OS/Kernel/shell 下看到“screen.linux”。
【解决方案3】:

检查您是否在屏幕中的替代方法。

类型:

Ctrl-a ?

如果您看到屏幕帮助,您就在屏幕中。

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

【讨论】:

  • 这当然假定Ctrl + a 是屏幕的命令字符。虽然这对大多数人来说都是正确的,但值得指出的是,命令字符可以被 -e 标志覆盖,所以这并不总是有效。
  • 这很好用(例如,Ctrl+a 然后“escape”)。虽然我猜如果您 not 在屏幕中,它可能会将您的光标移动到当前行的开头...:|
【解决方案4】:

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

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

【讨论】:

  • 有趣的方法。但是,您既不需要-p、head -n 1 | sed 's/\(.*\)+.*/\1/' 和wc -l,我建议将 -w 添加到 grep 以确保安全(它只会匹配名为“screen”而不是“screenish”的程序)。所以这是最后的命令pstree --show-parents $$|grep -w screen。但是,如果有人弄乱了您的环境变量,他也可能弄乱了可执行文件名称:)
【解决方案5】:

我对这个问题的解决方案要简单得多:如果您只需 点击 TAB 会使完整的终端闪烁(快速视频反转) 在 GNU Screen。

在大多数 Linux(Ubuntu、Kali、Debian、RaspBerry... 等)和 FreeBSD、GUI 和任何本地或远程终端(包括 CtrlAltFn 个。

作为此方法的一个例外,请注意这个(相当复杂但可能的)案例场景:

  • 1.- 通过 SSH 连接到计算机 A(假设是 Linux)。
  • 2.- 从计算机 A 上的远程终端输入一个新的screen -S AScr。
  • 3.- 从 GNU Screen AScr 终端通过 SSH 连接到计算机 B。
  • 4.- 从计算机 B 上的远程终端输入一个新的screen -S BScr。

您在案例 2 和 4 中位于 Screen 内,在案例 1 和 3 中位于 Screen 之外,但终端会在案例 2、3 和 4 时闪烁。

【讨论】:

    【解决方案6】:

    当 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

    【讨论】:

      【解决方案7】:

      将以下一项或多项添加到您的.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中。

      【讨论】:

      • 此方法的一种变体是将${TERM} 添加到$PS1 的提示中。这也可以在您的.bashrc 中完成。例如,如果您的$PS1 设置为[\u@\h \W]\$,那么您可以使用export PS1="[\u@\h ${TERM} \W]\$" 之类的内容进行更改
      • 我现在做这样的事情,除了有点花哨。 :)。当 $TERM == 'screen' 时,我在提示符的某个位置添加了一个明亮的“S”。无需任何输入即可始终知道我是否在其中变得微不足道。我将如何作为练习留给读者。
      【解决方案8】:

      上述大多数答案的问题在于,我们可能处于附加屏幕会话的 subshel​​l 中。或者我们可能会从屏幕会话中打开一个外壳到远程主机。在前一种情况下,我们可以遍历进程树父级并匹配screen 程序名称。在后一种情况下,大多数时候,我们可以检查TERM 变量中的screen* 之类的东西。

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

      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 总是被保留。
      • 它们在 startup 时被保留,但如果你放到子 shell 中则不一定(试试env -i bash)。或者,如果您连接的终端实际上​​是通过 ssh 连接到不同的主机,并且 TERM 变量在其他主机的 bashrc 中被覆盖。
      【解决方案9】:

      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.
      

      【讨论】:

      • 并非如此。仅仅因为一个屏幕是附加的并不意味着你在里面。它也可以从另一个终端附加/打开。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-11
      相关资源
      最近更新 更多