2013-12-10 13 views
1

我的主腳本在網關服務器上執行。它調用另一個腳本並在遠程服務器上執行它,但遠程腳本沒有確定的運行時間。所以我想禁用超時..如何禁用Net :: SSH :: Expect超時時間

好吧讓我解釋一下。

sub rollout 
{ 
(my $path, my $address)[email protected]_; 
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

我不知道是什麼問題。期待可以讓你不要超時。然後它應該永遠等待。我想你沒有給出超時執行命令,那麼發生了什麼呢? – DeVadder

+0

嗨,即使我有同樣的印象。但是看起來像默認情況下1秒超時。 – Jigar

+0

默認的超時時間爲1秒,但僅用於讀取操作。請參閱下面的答案。而且你甚至可以把它改成99999或者其他什麼。但要小心,^^ – DeVadder

回答

2

上不知道到底是怎麼回事錯讓我做瘋狂猜測答案。我是否應該錯誤地解釋你的問題,我將在稍後編輯:

Net :: SSH :: Expect的默認和強制超時只是讀取操作的超時。這並不意味着一個已啓動的腳本會在它的時間用完時被殺死,這只是意味着最後一次閱讀操作不再等待它說話。

您可以啓動遠程腳本,例如超時1秒,並且exec呼叫可能會在一秒鐘後返回。然後由exec返回的字符串將只包含遠程腳本輸出的第一秒。但是遠程腳本可能會繼續運行,您只需開始一個新的讀取操作(您可以選擇多個)來捕獲未來的輸出。遠程腳本(如果一切按預期工作)應該繼續運行,直到完成或關閉您的ssh連接。

這意味着,如果你只是exec,它將被殺死,等待它返回,然後關閉你的連接。一種方法是讓遠程腳本在完成時打印一些東西(「完成」時想到),並等待帶有非常高超時的waitfor的字符串,並且只在waitfor返回TRUE時關閉連接。或者,如果超時時間相當長,並且返回FALSE。如果你想監視你的腳本崩潰,我會建議在遠程機器上使用pgrep或ps。或者確保您的遠程腳本在處理時說了些什麼,例如使用eval{} or die "done"

編輯:

有一點要記住的是,這exec其實不是像system。它基本上發送命令到遠程shell並命中輸入。至少你是這樣看待發生的事情的。但是,看起來更像system,它會等待任何輸出的默認超時1秒,並將其存儲在自己的返回值中。可悲的是,它只是一個非常笨的閱讀操作,因爲它只是坐在那裏監聽,所以給它一個很長的超時或者實際使用它來與腳本進行交互並不是一個好主意。

我建議使用exec,超時時間爲0,然後使用waitfor,並且超時時間很長,以等待遠程腳本在完成後輸出的任何模式。只有然後關閉你的連接。

編輯2:

只是像更換您的EXEC:

$ssh->exec("/tmp/rollout.pl $path $address", 0); 
my $didItReturn = $ssh->waitfor("done", 300); 

並確保rollout.pl打印 「完成」,當它完成。而不是之前。現在這將啓動腳本,然後等待5分鐘以完成「完成」。如果一個「完成」出現,$ didItReturn將是真實的,如果超時,它將是錯誤的。如果看到「完成」,則不會等待5分鐘(而不是給予exec超時)。

編輯3:

如果你想沒有超時可言:

$ssh->exec("/tmp/rollout.pl $path $address", 0); 
my $didItReturn = 0; 
while ($didItReturn = 0) 
{ 
    $didItReturn = $ssh->waitfor("done", 300); 
} 
+0

好吧,讓我解釋一下。 $ ssh-> run_ssh()或死「SSH進程無法啓動:$!」; #開始交互式會話 $ ssh-> exec(「/ tmp/rollout.pl $ path $ address」); 當這部分代碼被執行時,會調用rollout.pl腳本,但是在一秒鐘後,該進程在遠程服務器上被終止 – Jigar

+0

那麼在exec之後,接下來會發生什麼?你關閉了連接嗎?銷燬'expect'對象?您等待的一秒鐘是'exec'的超時時間(順便說一句,這也是一個讀取操作),但腳本在返回後可能仍在運行。 'exec'只是停止等待其輸出。因此,您需要確保腳本在關閉連接之前以及遠程腳本運行的shell以及遠程腳本完成。 – DeVadder

+0

這裏的困惑是exec(scrip.pl)應該繼續在遠程服務器上執行並執行所有操作,但是它不會發生。執行命令後,我現在不執行任何活動 – Jigar