如何在ruby / bash脚本中杀死生成的子进程

时间:2014-08-28 05:13:52

标签: ruby linux bash raspberry-pi spawn

我对Linux世界一般都很陌生。我正在尝试为RaspPi构建一个记录音频并播放它的小脚本。它做得更多,但这是我遇到麻烦的部分。这是相关代码的精简版

def start_recording
  @file = rand(1000).to_s+".wav"
  @pid = Process.spawn("sudo arecord > #{@file}")
end

def stop_recording
  Process.kill('TERM', @pid)
end

def recording_looper
  start_recording
  interrupted = false
  timer = Time.now
  trap("INT") { interrupted = true }
  until interrupted || (Time.now > timer + 5) do
    #do nothing
  end
  stop_recording
  get_input_from_user
end

基本上looper按预期工作,要么从用户捕获Control-C,要么在5秒后停止录制,但Process.kill命令似乎不起作用。如果我在另一个终端窗口听取wavs,他们就会继续前进。如何正确杀死产生的记录过程?

2 个答案:

答案 0 :(得分:1)

您在命令行中调用sudosudo将在启动请求的命令后终止。存储在@pid中的PID将是sudo的{​​而不是arecord进程的PID。

此外,以sudo开头的流程属于另一个用户(通常为root)。您可能没有权限杀死它们。

解决问题的最简单方法可能是找到一种不需要sudo的方法。这里没有明显的理由要求root权限。

答案 1 :(得分:-1)

这是一个bash示例,证明您可以sudo kill进程(我在Ubuntu上执行此操作):

#!/bin/bash

sudo -u `whoami` sleep 600 &

pid=$!

echo "Processes before kill:"
ps axf | grep sudo | grep -v grep
ps axf | grep sleep | grep -v grep

sudo kill $pid

echo "Processes after kill (should be empty):"
ps axf | grep sudo | grep -v grep
ps axf | grep sleep | grep -v grep

结果如下:

$ ./test.sh 
Processes before kill:
27275 pts/26   S+     0:00          |   |       \_ sudo -u username sleep 600
27275 pts/26   S+     0:00          |   |       \_ sudo -u username sleep 600
27279 pts/26   S+     0:00          |   |       |   \_ sleep 600
Processes after kill (should be empty):

所以,要杀死它,你可以在Ruby或Bash中用sudo kill执行另一个命令。