我的主脚本在网关服务器上执行。它调用另一个脚本并在远程服务器上执行它,但远程脚本没有明确的运行时间。所以我想禁用超时..
好的,让我解释一下。
sub rollout
{
(my $path, my $address)=@_;
my $errorStatus = 0;
print "Rollout process being initiated on netsim\n";
#Creating SSH object
my $ssh = Net::SSH::Expect-> new (
host => "netsim",
user => 'root',
raw_pty => 1
);
#Starting SSH process
$ssh->run_ssh() or die "SSH process couldn't start: $!";
#Start the interactive session
$ssh->exec("/tmp/rollout.pl $path $address", 30);
return $errorStatus;
}
当执行这部分代码时,会调用rollout.pl脚本,但是在一秒钟之后,进程会在远程服务器上被终止
答案 0 :(得分:2)
如果不确切知道出了什么问题,请让我对答案做出疯狂猜测。如果我没有解释你的问题,我会稍后编辑:
Net :: SSH :: Expect的默认和强制超时只是读操作的超时。这并不意味着,一个已启动的脚本将在其时间用完时被杀死,这只意味着最后一次读取操作不再等待它说出来。
您可以启动远程脚本,例如超时为1秒,exec调用可能会在一秒后返回。 exec
返回的字符串将只包含远程脚本输出的第一秒。但是远程脚本可能会继续运行,您只需要启动一个新的读取操作(有几个可供选择)来捕获未来的输出。远程脚本,如果一切正常工作,应该继续运行,直到完成或关闭ssh连接。
这意味着,如果你只是执行,它会被杀死,等待返回然后关闭你的连接。一种方法是让远程脚本在完成时打印一些内容(想到“完成”)并等待具有非常高超时的waitfor
的字符串,并且只在{{1时关闭连接已返回TRUE。或者,如果超时相当长,那么当它返回FALSE时。如果你想监视你的脚本崩溃,我建议在远程机器上使用pgrep或ps。或者确保您的远程脚本在死亡时说出某些内容,例如使用waitfor
。
编辑:
要记住的一件事是,eval{} or die "done"
实际上不是exec
。它基本上将命令发送到远程shell并命中输入。至少这是你如何想象正在发生的事情。但是,为了看起来更像system
,它会等待任何输出的默认超时1秒,并将其存储在自己的返回值中。可悲的是,这是一个相当愚蠢的阅读操作,因为它只是坐在那里听,所以给它一个高超时或实际使用它与脚本交互不是一个好主意。
我建议使用超时为0的system
,然后使用具有非常高超时的exec
等待远程脚本在完成后输出的任何模式。然后才关闭你的连接。
编辑2:
只需用以下内容替换你的exec:
waitfor
确保rollout.pl在完成后打印“完成”。而不是之前。现在这将启动脚本,然后等待最多5分钟的“完成”。如果“完成”出现,$ didItReturn将成立,如果超时,则为假。如果它看到“完成”(而不是给$ssh->exec("/tmp/rollout.pl $path $address", 0);
my $didItReturn = $ssh->waitfor("done", 300);
超时),它将不会等待5分钟。
编辑3:
如果您不想要超时:
exec