(或如何杀死子进程)?
inotifywait -mqr --format '%w %f %e' $feedDir | while read dir file event
do
#something
done &
echo $! #5431
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
似乎我杀了5431然后5430(inotifywait)将继续运行,但是如果我杀死了5430,那么两个进程都会死掉.我不认为我可以可靠地假设inotifywait的pid总是比$低1!
最佳答案 当我们运行管道时,每个命令都在一个单独的进程中执行.解释器等待最后一个但是如果我们使用&符号(&).
cmd1 | cmd2 &
流程的pid可能很接近,但我们不能可靠地假设它.在最后一个命令是bash保留字的情况下,它会创建一个专用的bash(这就是为什么你的’dir’,’file’变量在done关键字之后不存在).例:
ps # shows one bash process
echo "azerty" | while read line; do ps; done # shows one more bash
当第一个命令退出时,第二个命令将终止,因为管道上的读取返回EOF.
当第二个命令退出时,第一个命令将在尝试写入管道时由signal SIGPIPE终止(在没有读取器的管道上写入).但是如果命令无限期地等待……它就不会被终止.
回声“$!”打印在后台执行的最后一个命令的pid.在您的情况下,正在执行while循环的bash进程.
您可以使用以下语法找到“inotifywait”的pid.但这很糟糕:
(inotifywait ... & echo "$!">inotifywait.pid) | \
while read dir file event
do
#something
done &
cat inotifywait.pid # prints pid of inotifywait
如果您不想要pid,但只是确保该进程将被终止,您可以使用inotifywait的-t选项:
(while true; do inotifywait -t 10 ...; done)| \
while read dir file event
do
#something
done &
kill "$!" # kill the while loop
这个解决方案都不好.你的真正成就是什么?也许我们可以找到更优雅的解决方案.