Scripting 完全透明、自动地使用GNU屏幕
屏幕是惊人的,当然,但我不想去想它。我经常ssh到一台机器上,开始做一些事情,然后想“天哪,我真希望我在做这些事情之前先想到启动一个屏幕会话,这样我以后就可以从家里重新连接到这个” 我想让屏幕自动启动,每当我登录到一台机器。 当我断开连接时,我希望能够立即简单地重新连接,而不必担心“screen-ls”和“screen-dr”Scripting 完全透明、自动地使用GNU屏幕,scripting,automation,ssh,gnu-screen,Scripting,Automation,Ssh,Gnu Screen,屏幕是惊人的,当然,但我不想去想它。我经常ssh到一台机器上,开始做一些事情,然后想“天哪,我真希望我在做这些事情之前先想到启动一个屏幕会话,这样我以后就可以从家里重新连接到这个” 我想让屏幕自动启动,每当我登录到一台机器。 当我断开连接时,我希望能够立即简单地重新连接,而不必担心“screen-ls”和“screen-dr” 我有一个脚本,它实现了这个问题的一个解决方案,我将作为答案发布。我想看看其他方法。取决于您的shell,但是.bashrc呢?(如果您使用bash“screen-rd”)
我有一个脚本,它实现了这个问题的一个解决方案,我将作为答案发布。我想看看其他方法。取决于您的shell,但是.bashrc呢?(如果您使用bash“screen-rd”)请使用以下
ssc
,而不是ssh
。如果您只需执行“ssc remote.com
”,它将列出现有的屏幕会话。给它第三个参数,它将连接到该屏幕会话,或者创建它并连接到它。无论哪种方式,如果断开连接,只需在shell中执行“向上箭头,输入”即可重新连接。零屏幕知识要求!
编辑:感谢@klochner将其扩展到处理任意ssh选项。您现在可以像ssh一样使用它了
#!/usr/bin/env perl
# Use 'ssc' (this script) instead of 'ssh' to log into a remote machine.
# Without an argument after the hostname it will list available screens.
# Add an argument after the hostname 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.
# ssh option parsing by @klochner
my $optstring = "";
while ($val = shift) {
if ($val =~ /^-\w$/) { $optstring .= " ".$val.(shift); }
elsif ($val =~ /^-\w+$/) { $optstring .= " ".$val; }
elsif ($machine) { $tag = $val; }
else { $machine = $val; }
}
if (!$machine) {
print "USAGE: ssc [ssh options] remote.com [screen name]\n";
} elsif (!$tag) {
@screens = split("\n", `ssh $optstring $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"; }
# remember anything weird about the screen, like shared screens
if($status =~ /^(attached|detached)$/i) {
$special{"$num.$tag"} = "";
} else {
$special{"$num.$tag"} = "[$status]";
}
}
}
print "ATTACHED:\n";
for(sort { ($a=~/\.(\w+)/)[0] cmp ($b=~/\.(\w+)/)[0] } keys(%att)) {
($tag) = /\.(\w+)/;
print " $tag\t($_)\t$special{$_}\n" if $att{$_};
}
print "DETACHED:\n";
for(sort { ($a=~/\.(\w+)/)[0] cmp ($b=~/\.(\w+)/)[0] } keys(%att)) {
($tag) = /\.(\w+)/;
print " $tag\t($_)\t$special{$_}\n" unless $att{$_};
}
} else {
system("ssh $optstring -t $machine \"screen -S $tag -dr || screen -S $tag\"");
}
顺便说一句,当您失去网络连接时,有一个技巧可以强制退出ssh会话并返回本地终端提示:是否可以将
exec screen-dr
放在您的.login中?我的.bashrc中有以下内容
if [ "$PS1" != "" -a "${_STARTED_SCREEN:-x}" = x -a "${SSH_TTY:-x}" ]
then
export _STARTED_SCREEN=1;
sleep 1
screen -RR && exit 0
# normally, execution of this rc script ends here...
echo "Screen failed! continuing with normal bash startup"
fi
我不久前在网上找到的,不知道在哪里
更新修复了评论中指出的错误。感谢R.Pate实际上screen将术语变量设置为“screen”。所以脚本更容易。以下是我使用的:
if [ "$TERM" != "screen" ]; then
screen -xRR
fi
工作起来就像一个符咒,-x
确保即使屏幕连接到其他地方,我也会将其连接到这里。这样,我只有一个屏幕可以跟踪所有内容。有一个屏幕可以自动重新连接断开的ssh会话
它附带了一个名为rscreen
的示例脚本,该脚本正是这样做的。简单来说就是:
#!/bin/sh
autossh -M 0 -t $1 "screen -e^Aa -D -R"
然后你必须重新训练你的手指来键入
rscreen hostname
,而不是ssh hostname
我用过autosh,它对我很有用
ssh user@host.com -t 'screen -dRR'
这将在connect上重新加载/创建屏幕会话。这完全符合请求,即使它将生成会话的责任转移到发起会话的客户端。理想情况下,您希望服务器上有一些进程来管理呈现给连接客户端的内容。据我所知,那是不存在的。没有人提出过这方面的理想解决方案。对我来说,这并不像其他人那么“不理想”。没有脚本,没有bug,没有TTY问题,没有与其他ssh命令的不良交互,没有无限循环的可能性,没有文件编辑,不需要额外的包 我使用。即使您进入睡眠模式、断开网络连接、更改IP等,它也会保持连接。无论何时你回来,你都可以恢复连接 “export\u STARTED\u SCREEN=1”而不是先设置然后导出,这难道还不够吗?@RogerPate不,之前先设置然后导出实际上更好——这样它实际上是可移植的,并且可以在其他兼容POSIX的shell上工作。现在它小了几个字节,但如果使用dash而不是bash等,它会断开。例如,请参阅screen在屏幕名称上的不可见和无声的制表符补全太聪明了,我建议使用一种惯例,确保您使用的每个屏幕名称都以一个不同的字母开头。在我的Ubuntu系统(10.4)上,我不得不修改正则表达式,以说明它在每个会话旁边打印的日期/时间信息。如果(/^\s*(\d+)\(\s+)\s+([^)]*)/(([^)]*){($num,$tag,$status)=($1,$2,$4);如果用户运行“ssh hostname'ls-R~/.local”该怎么办例如?@highperformance:是什么让你认为你无法签入。如果你已经在屏幕上运行bashrc?你是否还需要一个警告,告诉你一杯咖啡可能热了?你可以检查,但要正确或简洁地进行检查并不容易。天真的方法会破坏say
ssh主机“echo hello world”
。请参阅另一个示例回答。