在管道中较早获取命令的PID


11

我正在编写一个bash脚本,用于inotifywait监视目录并在检测到更改时启动操作。就像是:

inotifywait -m ... | while read f; do something; done

由于inotifywait不会自行终止,因此该脚本不会停止。

所以我的计划是获取inotifywait进程的PID,将其保存到文件中,然后让另一个进程将其杀死,例如:

inotifywait -m ... | { echo ??PID?? > pid-file; while ... }

但我不知道如何获取PID。有没有简单的方法可以做到这一点?另一种方法是将shell脚本的PID保存$$到文件中并杀死整个shell脚本,但是我想在while循环后进行一些清理。

我已经尝试过使用coproc,但我认为它会起作用,但似乎比所需的更为复杂。


您可以使用类似`ps -ef |的东西。grep processName | grep -v grep | awk'{print $ 2}'| xargs kill
-9`– Kiwy

@Kiwy-要做一个而不是一团糟pgrep inotifywait。那会给你PID,杀死pkill inotifwait
slm

@slm取决于您的系统,而几乎没有grep和ps时,您将没有pgrep和pkill。不客气
Kiwy

@Kiwy-令人怀疑的是,这些工具无处不在。另外,您不需要执行grep -v grep,而是ps -ef | grep [p]rocessname...会执行相同的操作。
slm

1
@DavidsonChua-是的,-f如果需要与更多可执行文件名称匹配,可以使用该开关。
slm

Answers:


6

在管道中,所有进程都是同时启动的,没有一个比其他进程

您可以这样做:

(echo "$BASHPID" > pid-file; exec inotifywait -m ...) | while IFS= read -r...

或可移植:

sh -c 'echo "$$" > pid-file; exec inotifywait -m ...' | while IFS= read -r...

还要注意,当运行while循环的子shell 终止时,inotifywait下次将其写入stdout时将自动终止。


3

如果您需要循环中的进程ID,请首先打印它。

sh -c 'echo "$$"; exec inotifywait -m ...' | {
  read inotifywait_pid
  while IFS= read -r f; do
    
    if …; then kill "$inotifywait_pid"; break;
  done
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.