补充:我相信现在这个问题归于这一问题: Using GNU Screen completely transparently and automatically
原始问题:
如果有一种方法可以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的可用屏幕。
我现在根据Jason的答案使用以下别名(tcsh)连接到命名屏幕(如果存在)或创建并以其他方式连接:
alias ssc 'ssh -t \!:1 "screen -S \!:2 -dr || screen -S \!:2"'
答案 0 :(得分:58)
-t
选项是否符合您的要求?
-t Force pseudo-tty allocation. This can be used to execute arbi- trary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty.
所以:
laptop> ssh -t server.com screen -dr pts-2
这似乎适用于我的安装。
答案 1 :(得分:3)
现在这包含在:Using GNU Screen completely transparently and automatically
中<小时/> 这是一个脚本
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\"");
}
答案 2 :(得分:2)
使用-t
选项ssh在直接运行命令时分配终端。
laptop> ssh -t server.com screen -dr pts-2
答案 3 :(得分: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"
答案 4 :(得分:1)
我将此转换为在OS X .bash_profile上添加一个:如果没有给出第二个参数,它将启动会话“default”。
function ssc() {
if [[ -z $2 ]]; then
screen="default"
else
screen=$2
fi
ssh -t $1 "screen -S $screen -dr || screen -S $screen"
}
答案 5 :(得分:1)
如果您想连接到同一个会话,即使它已处于活动状态,已分离或尚未存在:
ssh -t user @ server screen -xR screenName
同样但如果它已在其他某个pty上处于活动状态,则创建一个新会话:
ssh -t user @ server screen -rR screenName