【发布时间】:2014-05-12 11:53:26
【问题描述】:
我需要在后台通过 $ssh->system 执行命令,据记录,这应该就像本地“系统”命令一样:
'As for "system" builtin, "SIGINT" and "SIGQUIT" signals are blocked. (see "system" in perlfunc).'
实际上,这似乎不是真的,因为 $ssh-> 子系统在收到 SIGINT 时立即终止,即使我明确想先“忽略”它:
use warnings;
use strict;
use POSIX ":sys_wait_h";
use Net::OpenSSH;
my $CTRLC=0;
$SIG{CHLD}='IGNORE';
sub _int_handler {
$CTRLC++;
print "CTRL-C was pressed $CTRLC times!!!\n";
}
$SIG{INT}='IGNORE';
my $SSH=Net::OpenSSH->new('testhost',
forward_agent => 1,
master_stderr_discard => 1,
master_opts => [ -o =>"PasswordAuthentication=no"]);
$SIG{INT}=\&_int_handler;
sub _ssh {
$SIG{INT}='IGNORE';
$SSH->system('sleep 3; sleep 3');
# system('sleep 3; sleep 3');
print "Exiting Child!\n";
exit 0;
}
print "Starting shell ...\n";
_ssh if not (my $PID=fork);
print $PID, "\n";
waitpid ($PID,0);
当运行此代码并在第一个“sleep 3”开始后尝试中断时,“$SSH->system”调用立即结束。
但是,如果您使用下面的本地“系统”语句,则可以正确捕获 SIGINT。
在 Net::OpenSSH 的源代码中,我发现 $SIG{INT} 在“system”子项中也显式设置为“IGNORE”。我不知道为什么这不起作用。
如果这意味着以不同的方式做事,我们会感谢任何可能的解决方案。最后,我只想远程执行命令并且仍然保护它们免受 CTRL-C 的影响。
谢谢,
迷宫
更新:
感谢您的意见@salva。我进一步剥离了一些东西,最后它似乎是 ssh 的“-S”标志:
$SIG{INT}='IGNORE';
# system('ssh -S /tmp/mysock lnx0001a -- sleep 3');
system('ssh lnx0001a -- sleep 3');
一旦使用“-S /tmp/mysock”变体,ssh 似乎是可中断的,否则不会。有没有人可以对此作出解释? 我应该为此发布一个新的独立问题吗?
再次感谢,
迷宫
更新 2:
我把事情做得更多了,现在这完全没有任何 perl 范围。你可以在你的 shell 中做到这一点:
$ trap '' INT
$ ssh lnx0001a -- sleep 3
现在不可中断。 然而,就我而言,以下内容仍然是可中断的:
$ ssh -S /tmp/mysock lnx0001a -- sleep 3
使用 CTRL-C,这会立即中断。 root 用户的情况与我的情况相同,但其他同事在他们的用户中看不到这种行为。我们比较了@ENV,但没有找出可能导致不同行为的原因。
你的情况如何:在你的 shell 中的“trap '' INT”之后,“-S”版本是否可以中断? (显然,您之前必须为 /tmp/mysock 创建主会话)。
此致,
迷宫
【问题讨论】:
-
@Mazze,查看我的更新回复。
标签: perl perl-module openssh