networking中断后自动(或更容易)重新连接到屏幕会话

补充:我相信,现在这个问题包含在这个问题中: 完全透明地自动使用GNU Screen

另请参阅以下相关问题:
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 

但是失败了,说“必须连接到terminal”。 你必须首先ssh,然后在server.com上执行“screen -dr pts-2”,如果你有一个脆弱的连接并断开很多,那么这是不好的。 您希望能够在笔记本电脑上使用简单的“向上箭头键”进行恢复。 (或者也许使它更自动化。)

对于这个问题,我有一个匪夷所思的解决scheme,我会作为答复发表意见,希望得到的结果是被遗忘而转移到正确的方式来解决这个问题。


脚注:

或者,更好的是,如果您使用“ screen -S foo ”和“ screen -S bar ”等名称创build了屏幕会话,那么您将得到一个更友好的列表,如:

 123.foo 456.bar 

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


迷你屏幕教程,结合这个问题的答案:

login到server.com并执行

 screen -S foo 

然后再也不会从该会话中注销。 要从其他地方重新连接,请执行

 ssh -t server.com screen -dr foo 

要列出可用屏幕以重新调用:

 screen -ls 

或者,当然,

 ssh server.com screen -ls 

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

我现在使用下面的别名(tcsh),基于贾森的回答下面,连接到一个命名的屏幕,如果它存在或创build和连接,否则:

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

-t选项可以做你想要的吗?

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

所以:

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

这似乎在我的安装。

现在,这包括: 完全透明和自动地使用GNU屏幕


这是一个脚本, 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\""); } 

使用-t选项ssh在直接运行命令的同时分配terminal。

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

我一直在做类似的事情,但没有达到那里,你的解决scheme已经解决了我的问题,所以这是我的build议:

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

这只是试图打开名为foo的现有屏幕,如果它不存在,创build它。 我会把它放在我的笔记本电脑上的一个启动器上,所以当无线networking进入时,我可以打开我离开的地方。

刚刚注意到,默认的屏幕shell有点弱,所以改善一下你的家庭环境的好处是:

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

我转换这个工作在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" } 

如果你喜欢连接到相同的会话,即使它是活动的,分离或不存在:

ssh -t user @ server screen -xR screenName

同样的,但创build一个新的会话,如果它已经有一些其他的pty:

ssh -t user @ server screen -rR screenName