2017-08-01 83 views
0

我在一個阿爾卑斯碼頭集裝箱運行紅寶石(這是一個sidekiq工人,如果有的話)。在某個時候,我的應用程序會收到一些指令,將其發送給一個子命令。我需要能夠流化STDOUT而不是緩衝。這就是爲什麼我使用PTY而不是system()或其他類似的答案。我執行下面的代碼行:無法發送信號到由PTY.spawn()在Ruby創建的進程

stdout, stdin, pid = PTY.spawn(my_cmd) 

當我連接到泊塢窗容器和運行PS auxf,我看到:

root   7 0.0 0.4 187492 72668 ?  Sl 01:38 0:00 ruby_program 
root  12378 0.0 0.0 1508 252 pts/4 Ss+ 01:38 0:00 \_ sh -c my_cmd 
root  12380 0.0 0.0 15936 6544 pts/4 S+ 01:38 0:00  \_ my_cmd 

注紅寶石的子進程如何爲「sh -c my_cmd「,它本身就有一個孩子」my_cmd「進程。

「my_cmd」可能需要很長時間才能運行。它被設計成發送一個信號USR1到進程使它保存它的狀態,以便它可以稍後恢復並中止清理。

問題是,從「PTY.spawn()」返回的pid是「sh -c my_cmd」進程的pid,而不是「my_cmd」進程。所以當我執行時:

Process.kill('USR1', pid) 

它將USR1發送到sh而不是my_cmd,因此它不像它應該那樣工作。

有什麼辦法可以獲得與我實際指定的命令相對應的pid嗎?我接受PTY以外的想法,但它需要滿足以下約束條件:

1)我需要能夠在寫入STDOUT和STDERR時對其輸出進行流式處理,而無需等待它們被刷新(因爲STDOUT和STDERR在PTY中混合成一個流,我將STDERR重定向到一個文件並使用inotify獲取更新)。

2)我需要能夠發送USR1到進程,以便能夠暫停它。

回答

0

我放棄了一個乾淨的解決方案。我終於執行了

pgrep -P #{pid} 

得到孩子pid,然後我可以發送USR1到那個過程。感覺哈克,但是當紅寶石給你檸檬...

+0

順便說一句,pgrep不是一個紅寶石命令。爲了解決這個問題,我不得不再次掏腰包。 –