screen -R 无法与 ssh 配合使用

screen -R 无法与 ssh 配合使用

我在办公室里有一台 Linux 机器,我想通过家里的 Macbook 来 ssh 连接它。我无法直接通过端口 22 连接该机器,但我在 localhost:23001 和远程 Linux 机器上的端口 22 之间建立了一个端口隧道。这适用于常规 ssh 会话:

$ ssh -t -2 -A -p 23001 [email protected]

下一步是,我想在屏幕会话中自动运行我的终端会话。它几乎可以做到:

$ ssh -t -2 -A -p 23001 [email protected]  screen -R

如果我没有当前屏幕会话,它会创建一个。如果已经有一个分离的屏幕,它会连接到它。到目前为止,一切顺利。但问题是,我从来没有得到一个登录 shell,所以我的 .profile 从来没有运行过,我的环境也没有设置好。所以,我更进一步,尝试了:

$ ssh -t -2 -A -p 23001 [email protected]  bash -l -c screen -R

现在,我得到了一个运行 .profile 的真正的登录 shell,但屏幕无法重新连接到分离的会话。我在 Macbook 上运行上述命令,在远程机器上,我得到了一个连接的屏幕:

$ screen -list
There is a screen on:
    21117.pts-21.roysmith01 (01/19/2015 01:50:59 PM)    (Attached)
1 Socket in /var/run/screen/S-roysmith.

如果我关闭运行上述 ssh 行的窗口,会话就会分离,正如预期的那样:

$ screen -list
There is a screen on:
    21117.pts-21.roysmith01 (01/19/2015 01:50:59 PM)    (Detached)
1 Socket in /var/run/screen/S-roysmith.

现在,如果我打开另一个本地终端窗口并再次运行该 ssh 命令,screen 将无法找到分离的会话并创建一个新的会话:

$ screen -list
There are screens on:
    21304.pts-21.roysmith01 (01/19/2015 01:52:40 PM)    (Attached)
    21117.pts-21.roysmith01 (01/19/2015 01:50:59 PM)    (Detached)
2 Sockets in /var/run/screen/S-roysmith.

知道这是怎么回事吗?为什么插入登录 shell 会导致屏幕无法找到现有会话?

答案1

如果没有现有的会话可以连接,screen 将使用你给出的任何命令标志-R。因此这应该可以实现您想要的功能(无需触碰 .screenrc):

$ ssh [...]@127.0.0.1 screen -R bash -l

(这肯定是完成您最初计划要做的事情的最简单的方法。)

但既然你问了,我也要说一下为什么你的bash -l方法没有奏效。它已经很接近成功了!

bash -c仅将紧接着的下一个参数作为命令。之后的参数将进入$0$1等。

$ bash -c echo bar
[just a blank line]
$ bash -c 'echo foo'
foo
$ bash -c 'echo $1' foo bar baz
bar

这完成了你想做的事情bash -l -c screen -R

$ ssh [...]@127.0.0.1 bash -l -c "'screen -R'"

是的,令人兴奋的是,您需要两层引号才能实现该功能:外层引号告诉您的本地 shell 保留内层引号,而内层引号是必需的,因为 ssh 将结果命令 发送为包含bash -l -c 'screen -R'四个空格的字符串,而不是四个单词的列表。使用一层引号,远程 shell 仍将看到bash -l -c screen -R

这也可以做到这一点,远程 shell 被赋予命令字符串bash -l -c screen\ -R

$ ssh [...]@127.0.0.1 bash -l -c 'screen\ -R'

或者这样给出远程 shell bash -l -c "screen -R"

$ ssh [...]@127.0.0.1 bash -l -c \"screen -R\"

答案2

我发现我如何让屏幕表现得像一个标准的 bash shell?,这为我指明了正确的方向。在我的 .screenrc 中输入“defshell -bash”可以实现我想要的行为。但是,我可以弄清楚 screen 到底在做什么。我讨厌在不理解原因的情况下找到有效的东西。

相关内容