2017-08-01 53 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不是一个红宝石命令。为了解决这个问题,我不得不再次掏腰包。 –