2012-11-19 36 views
4

我正在使用net :: ssh2創建SSH連接到遠程服務器。我選擇了Net :: SSH2,因爲我不得不在同一個腳本中創建一些SFTP連接。我選擇了Net :: SSH2,因爲我不得不在同一個腳本中創建一些SFTP連接。[net] [net :: ssh2]如何在執行遠程命令時保持ssh連接

現在,我的sftp連接完美地工作。問題是當我嘗試執行「長時間」命令。我的意思是執行可能需要超過30秒的命令。

$ssh2 = Net::SSH2->new(); 
    $ssh2->connect('HOST') or die; 
    if($ssh2->auth(username=>'USER', password=>'PSWD')) 
    { 
     $sftp = Net::SFTP::Foreign->new(ssh2=>$ssh2, backend=>'Net_SSH2'); 
     $sftp->put('local_path', 'remote_path'); 
     $channel=$ssh2->channel(); 
    ## 
     $channel->shell('BCP_COMMAND_OR_OTHER_PERL_SCRIPT'); 
    # OR (I tried both, both failed :() 
     $channel->exec('BCP_COMMAND_OR_OTHER_PERL_SCRIPT'); 
    ## 
     $channel->wait_closed(); 
     $channel->close(); 
     print "End of command"; 
     $sftp_disconnect(); 
    } 
    $ssh2->disconnect(); 

當我執行該腳本,則連接是全成,該文件是正確發送,但執行不是(完全地)執行。我的意思是,我認爲命令被髮送執行,但立即終止或根本不發送,我不知道。

我要的是腳本等待,直到命令完成完全地斷開連接之前的一切(只是因爲有時候,我需要得到命令執行的結果)

有誰知道如何解決這個問題? :(CPAN的文件是不是這個

感謝

PS很明確:我歡迎任何評論或建議:)

編輯:一些測試後,我可以說,命令被髮送但被中斷。我的測試是在遠程服務器上啓動另一個perl腳本。這個腳本寫在一個平面文件中。在這個測試中,腳本啓動,文件被半滿。我的意思是,文件被中間停下來。另一方面,當我在「$ channel-> exec()」後面執行「sleep(10)」時,腳本成功完成。 問題是,我不能寫一個「睡眠(10)」(我不知道這是否將採取9秒或11秒(或更多,你明白我的意思)

回答

2

您可以嘗試使用Net::SSH::Any代替。

它提供了一個更高的層次和更容易使用的API,可以使用Net :: SSH2或Net :: OpenSSH的處理SSH連接

例如:

use Net::SSH::Any; 

my $ssh = Net::SSH::Any->new($host, user => $user, password => $password); 
$ssh->error and die $ssh->error; 

my $sftp = $ssh->sftp; 
$sftp->put('local_path', 'remote_path'); 

my $output = $ssh->capture($cmd); 
print "command $cmd output:\n$output\n\n"; 

$sftp->put('local_path1', 'remote_path1'); 

# no need to explicitly disconnect, connections will be closed when 
# both $sftp and $ssh go out of scope. 

注意,SFTP支持(通過Net :: SFTP :: Foreign)已添加到版本0.03上我剛剛上傳到CPAN。

+0

謝謝!它完美的工作! 我希望這個軟件包的文檔很快就會增長 –

+0

不會在長時間的命令工作中使用nohup嗎? – Rooster

+0

'nohup'用例不同:它允許讓命令在完全脫離SSH會話的背景上運行,然後可以關閉該會話。 – salva