(或如何杀死子进程)?
inotifywait -mqr --format '%w %f %e' $feedDir | while read dir file event
do
#something
done &
echo $! #5431
Run Code Online (Sandbox Code Playgroud)
ps例如:
>$ ps
PID TTY TIME CMD
2867 pts/3 00:00:02 bash
5430 pts/3 00:00:00 inotifywait
5431 pts/3 00:00:00 bash
5454 pts/3 00:00:00 ps
Run Code Online (Sandbox Code Playgroud)
看来,如果我杀死5431,则5430(inotifywait)将保持运行,但是如果我杀死5430,则两个进程都将死亡。我想我不能可靠地假设inotifywait的pid 总是比$小1!?
当我们运行管道时,每个命令都在单独的进程中执行。解释器会等待最后一个,但如果我们使用与号(&)。
cmd1 | cmd2 &
Run Code Online (Sandbox Code Playgroud)
进程的 pid 可能很接近,但我们不能可靠地假设它。如果最后一个命令是 bash 保留字 while,它会创建一个专用的 bash(这就是为什么在 did 关键字之后不会存在“dir”、“file”变量)。例子:
ps # shows one bash process
echo "azerty" | while read line; do ps; done # shows one more bash
Run Code Online (Sandbox Code Playgroud)
当第一个命令退出时,第二个命令将终止,因为管道上的读取返回 EOF。当第二个命令退出时,第一个命令在尝试写入管道时将被信号SIGPIPE(在没有读取器的管道上写入)终止。但如果命令无限期地等待......它不会终止。
回声“$!” 打印后台执行的最后一个命令的 pid。在你的例子中,bash 进程正在执行 while 循环。
您可以使用以下语法找到“inotifywait”的pid。但它很丑陋:
(inotifywait ... & echo "$!">inotifywait.pid) | \
while read dir file event
do
#something
done &
cat inotifywait.pid # prints pid of inotifywait
Run Code Online (Sandbox Code Playgroud)
如果您不想要 pid,但只是确定进程将被终止,则可以使用 inotifywait 的 -t 选项:
(while true; do inotifywait -t 10 ...; done)| \
while read dir file event
do
#something
done &
kill "$!" # kill the while loop
Run Code Online (Sandbox Code Playgroud)
这些解决方案都不好。你真正的成就是什么?也许我们可以找到更优雅的解决方案。