Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm writing a bash script to use inotifywait to monitor a directory and kick off actions when changes are detected. Something like:

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

Since inotifywait doesn't terminate by itself, this script will not halt.

So my plan was to get the PID of the inotifywait process, save it to a file and have a different process kill it later, say like:

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

But I don't know how to get the PID. Is there a simple way to achieve this? Another way is just to save the PID of the shell-script $$ to the file and kill the entire shell-script but I wanted to do some cleanup after the while loop.

I have tried using coproc and I think it will work but it seems like more complication than necessary.

share|improve this question
You could use something like this ` ps -ef | grep processName | grep -v grep | awk '{print $2}' | xargs kill -9 ` – Kiwy Dec 3 '13 at 9:13
@Kiwy - instead of that mess just do a pgrep inotifywait. That will give you the PID,to kill, pkill inotifwait. – slm Dec 3 '13 at 12:42
@slm depending of your system you will not have pgrep and pkill while grep and ps while almost be present. You're welcome – Kiwy Dec 3 '13 at 12:48
@Kiwy - doubtful, those tools are pretty ubiquitous. Also you do not need to do a grep -v grep, instead ps -ef | grep [p]rocessname... would do the same. – slm Dec 3 '13 at 13:10
@DavidsonChua - yes you can use the -f switch if you need to match against more of the executables name. – slm Dec 4 '13 at 1:08
up vote 4 down vote accepted

In a pipeline, all processes are started concurrently, there's not one that is earlier than the others.

You could do:

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

Or portably:

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

Also note that when the subshell that runs the while loop terminates, intotifywait would be killed automatically the next time it writes something to stdout.

share|improve this answer

If you need the process ID in the loop, print it first.

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

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.