2017-05-19 56 views
0

我需要通過SSH啓動遠程Python腳本。遠程機器上的Python腳本需要執行一些文件操作,爲模擬啓動可執行文件(從幾小時到幾天),收集結果並寫入文件。Ruby Net/SSH - 啓動遠程Python腳本和分離

我使用Net-SSH exec!從Ruby啓動腳本。我使用頻道捕獲STDERRSTDOUT

腳本工作正常,但現在我想從本地Ruby腳本中分離遠程機器上的運行腳本。然後我會直接在遠程機器上檢查模擬的狀態。

我試圖用nohup來運行腳本。

Net::SSH.exec!("nohup python script.py args > out.log 2> err.log < /dev/null &") 

腳本被分離,我馬上回來的控制,但在遠程機器上的腳本就會被殺死,我無法找到後臺進程。

理想情況下,我會直接從Ruby啓動模擬可執行文件,但我必須使用Python,因爲我需要一些在Ruby中不可用的庫。

上述方法是否正確?我可以在網絡SSH上使用nohup嗎?

有沒有更好的方法?

編輯:

def self.ssh_exec!(ssh, cmd, log = nil) 

    ssh.open_channel do |ch| 

     ch.request_pty do |chan,success| 
     end 

     ch.exec(cmd) do |chan, success| 
     raise "could not execute command" unless success 

     # "on_data" is called when the process writes something to stdout 
     chan.on_data do |c, data| 
      log ? (log << data) : (puts data) 
     end 

     # "on_extended_data" is called when the process writes something to stderr 
     chan.on_extended_data do |c, type, data| 
      log ? (log.error data) : (puts data) 
     end 

     chan.on_close do 
      puts 'Done' 
     end 
     end 
    end  
    end 

然後我打電話

Net::SSH.start(aws_ip, user, options = aws_options) do |ssh| 

    script = File.join(path, 'pyfoam_scripts', 'run_case.py') 
    cmd = "source...; python #{script} #{dst_case}" 
    RG::Utils.ssh_exec!(ssh, cmd, @logger) 

    ssh.loop 
    end 

其中

:options => {:keys => path_to_key, 'key.pem'), 
         :keepalive => true, 
         :timeout => 3000, 
         :compression => true, 
         :compression_level => 6}, 
+1

發佈更多創建ssh連接的代碼會很有幫助;特別是我想知道是否爲啓動腳本的會話分配了PTY。也就是說,我沒有看到你發佈的那一行代碼有什麼問題。您應該嘗試弄清楚腳本發生了什麼,導致腳本退出。它獲得了一個信號?是否遇到其他問題並決定自行退出? – Kenster

+1

讓我重定向到[unix.stackexchange.com答案](https://unix.stackexchange.com/a/261631),我認爲你會發現它很有用。 恕我直言,從我看到的是沒有問題的Net :: SSH在你身邊。 –

+0

我已經添加了我的代碼提取 – Rojj

回答

0

一點更多的測試,並感謝我意識到的評論,有在三個錯誤後我代碼:

  1. 我正在使用channelsChannels用於建立與遠程機器的通信,捕獲輸出,使用回調。在這種情況下,我不需要這些。
  2. Net::SSH.exec!等待命令完成。我需要啓動並忘記。 (愚蠢的錯誤)
  3. ssh.loop是不需要的。請參閱1.

修復了上述錯誤之後,它就像一個魅力。