56

补充:我相信这个问题现在被这个问题所包含: Using GNU Screen fully transparent and automatic

另请参阅此相关问题:
https ://superuser.com/questions/147873/ssh-sessions-in-xterms-freeze-for-many-minutes-whenever-they-disconnect

原始问题:

如果有办法通过 ssh 连接到机器并立即重新连接到特定的屏幕会话,那就太好了。你可以这样做:

laptop> ssh server.com screen -ls

它将显示 server.com 上可用的屏幕列表,如下所示 [1]:

123.pts-1
456.pts-2

然后你可以尝试这样做:

laptop> ssh server.com screen -dr pts-2

但这失败了,说“必须连接到终端”。您必须先 ssh 进入,然后在 server.com 上执行“screen -dr pts-2”,如果您的连接不稳定并且经常断开连接,这将是不好的。您希望能够在笔记本电脑上通过简单的“向上箭头输入”来恢复。(或者也许让它更加自动化。)

对于这个问题,我有一个非常巧妙的解决方案,我将把它作为答案发布,并希望它被否决而被遗忘,以支持处理这个问题的正确方法。


脚注:

[1] 或者,更好的是,如果您使用“ screen -S foo”和“ screen -S bar”之类的名称创建屏幕会话,那么您将获得一个更友好的列表,例如:

123.foo
456.bar

并且可以重新连接,例如“ screen -dr foo”。


小屏教程,结合这个问题的答案:

登录到 server.com 并执行

screen -S foo 

然后再也不会退出该会话。要从其他地方重新连接到它,请执行

ssh -t server.com screen -dr foo

列出要重新连接到的可用屏幕:

screen -ls

或者,当然,

ssh server.com screen -ls

远程检查 server.com 的可用屏幕。

我现在使用以下别名 (tcsh),基于 Jason 在下面的回答,连接到命名屏幕(如果存在)或创建并连接:

alias ssc 'ssh -t \!:1 "screen -S \!:2 -dr || screen -S \!:2"'
4

6 回答 6

62

-t选项是否符合您的要求?

     -t 强制伪 tty 分配。这可以用来执行仲裁
             将基于屏幕的程序放在远程机器上,可以是
             非常有用,例如在实现菜单服务时。多个 -t
             即使 ssh 没有本地 tty,选项也会强制分配 tty。

所以:

laptop> ssh -t server.com screen -dr pts-2

这似乎适用于我的安装。

于 2009-01-23T23:08:59.533 回答
4

这现在被以下内容所包含: 完全透明和自动地使用 GNU Screen


这是一个脚本,ssc它的工作原理与此类似,ssh但需要第三个参数来指定要重新连接到的屏幕或新屏幕的名称。我相信这个脚本包含了原始问题中的所有内容。

#!/usr/bin/env perl
# Use 'ssc' (this script) instead of 'ssh' to log into a remote machine.
# Without a 3rd argument it will list available screens.
# Give it a 3rd argument to attach to an existing screen or specify a new
#   screen.  Eg, ssc remote.com foo
# The numbers in front of the screen tag can usually be ignored.
# Screen is a little too clever though in that if there's an existing screen "bar"
#   and you say "ssc remote.com b" it will reconnect you to "bar" instead of making
#   a new screen "b".  It's like invisible and silent tab-completion.

if(scalar(@ARGV)==0 || scalar(@ARGV) > 2) {
  print "USAGE: ssc remote.com [screen name]\n";
} elsif (scalar(@ARGV) == 1) {
  $machine = shift;
  @screens = split("\n", `ssh $machine screen -ls`);
  for(@screens) {
    if(/^\s*(\d+)\.(\S+)\s+\(([^\)]*)\)/) {
      ($num, $tag, $status) = ($1, $2, $3);
      if($status =~ /attached/i) { $att{"$num.$tag"} = 1; }
      elsif($status =~ /detached/i) { $att{"$num.$tag"} = 0; }
      else { print "Couldn't parse this: $_\n"; }
    }
  }
  print "ATTACHED screens:\n";
  for(keys(%att)) { print "  $_\n" if $att{$_}; }
  print "DETACHED screens:\n";
  for(keys(%att)) { print "  $_\n" unless $att{$_}; }
} else {
  $machine = shift;
  $tag = shift;
  system("ssh -t $machine \"screen -S $tag -dr || screen -S $tag\"");
}
于 2009-07-02T17:56:10.947 回答
2

使用-tssh 选项在直接运行命令时分配终端。

laptop> ssh -t server.com screen -dr pts-2
于 2009-01-23T23:10:00.700 回答
2

我一直在做类似的事情,但还没有做到,你的解决方案已经解决了我的问题,所以这是我的建议:

ssh -t server.com "screen -S foo -rd || screen -S foo"

这只是尝试打开名为 foo 的现有屏幕,如果它不存在,则创建它。我会把它放在我笔记本电脑的启动器中,所以当无线网络连接时,我可以在我离开的地方打开。

刚刚注意到默认的屏幕外壳有点弱,所以一个更好地设置你的家庭环境的改进是:

ssh -t server.com "screen -S foo -rd || screen -S foo bash -l"
于 2009-03-12T18:25:24.120 回答
1

我将其转换为在 OS X .bash_profile 上工作,并添加了一个:如果没有给出第二个参数,它将启动一个“默认”会话。

function ssc() {
    if [[ -z $2 ]]; then
        screen="default"
    else
        screen=$2
    fi
    ssh -t $1 "screen -S $screen -dr || screen -S $screen"
}
于 2013-09-06T06:34:40.760 回答
1

如果您想始终连接到同一个会话,即使它处于活动状态、已分离或尚不存在:

ssh -t user@server screen -xR screenName

相同,但如果它已经在其他一些 pty 上处于活动状态,则创建一个新会话:

ssh -t user@server screen -rR screenName

于 2015-11-26T13:50:22.917 回答