我需要通過$ 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);
運行此代碼並嘗試在第一個「睡眠3」開始後立即中斷,「$ SSH-> system」調用即刻我終於結束了。
但是,如果您使用下面的本地「系統」語句,SIGINT會被正確捕獲。
在Net :: OpenSSH的源代碼中,我發現$ SIG {INT}在「system」子版中也顯式設置爲「IGNORE」。我不知道爲什麼這不起作用。
我會感謝任何一種可能的解決方案,如果這意味着做不同的事情。最後,我只想遠程執行命令,並保護它們免受CTRL-C的影響。
謝謝
Mazze
UPDATE:
謝謝您的輸入@salva。我進一步剝離下來,最後它似乎是「-S」 SSH的標誌:
$SIG{INT}='IGNORE';
# system('ssh -S /tmp/mysock lnx0001a -- sleep 3');
system('ssh lnx0001a -- sleep 3');
一旦正在使用的「-S的/ tmp/mysock」變種,SSH似乎是可以中斷,否則。有沒有人可以給出解釋呢? 我應該爲此發佈一個新的獨立問題嗎?再次
感謝,
Mazze
更新2:
我把東西放下就更多了,現在這是完全沒有任何perl的範圍。你可以在你的外殼上做到這一點:
$ trap '' INT
$ ssh lnx0001a -- sleep 3
現在不可中斷。 在我的情況,但是,下面仍然是可中斷:
$ ssh -S /tmp/mysock lnx0001a -- sleep 3
使用CTRL-C,這個被立即中斷。 root用戶和我的情況是一樣的,但其他同事沒有看到他們的用戶有這種行爲。我們比較了@ENV,但我們沒有找出可能導致不同行爲的原因。
它是如何與你:「-S」版本是否可以在你的外殼「陷阱」「INT」後中斷? (很明顯,你必須在之前爲/ tmp/mysock創建一個主會話)。
此致
Mazze
@Mazze,看到我更新的回覆。 – salva