(or How to kill the child process)?
inotifywait -mqr --format '%w %f %e' $feedDir | while read dir file event
do
#something
done &
echo $! #5431
ps eg:
>$ 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
It seems if I kill 5431 then 5430 (inotifywait) will be left running, but if I kill 5430 then both processes die. I don't suppose I can reliably assume that the pid of inotifywait will always be 1 less than $!?
The ps command displays information about a selection of the active processes which includes the process ID (pid=PID), terminal associated with the process (tname=TTY), cumulated CPU time in [DD-]hh:mm:ss format (time=TIME), and executable name (ucmd=CMD). Output is unsorted by default.
As Linux users, we're familiar with process identifiers (PID). PID is the operating system's unique identifier for active programs that are running. A simple command to view the running processes shows that the init process is the owner of PID 1.
When we run a pipe, each command is executed in a separated process. The interpreter waits for the last one but if we use ampersand (&).
cmd1 | cmd2 &
The pid of processes will be probably close, but we cannot assume it reliably. In the case where the last command is a bash reserved word as while, it creates a dedicated bash (that's why your 'dir', 'file' variables won't exist after the done keyword). Example:
ps # shows one bash process
echo "azerty" | while read line; do ps; done # shows one more bash
When the first command exits, the second one will terminate because the read on the pipe return EOF. When the second command exits, the first command will be terminated by the signal SIGPIPE (write on a pipe with no reader) when it tries to write to the pipe. But if the command waits indefinitely... it is not terminated.
echo "$!" prints the pid of the last command executed in background. In your case, the bash process that is executing the while loop.
You can find the pid of "inotifywait" with the following syntax. But it's uggly:
(inotifywait ... & echo "$!">inotifywait.pid) | \
while read dir file event
do
#something
done &
cat inotifywait.pid # prints pid of inotifywait
If you don't want the pid, but just be sure the process will be terminated, you can use the -t option of inotifywait:
(while true; do inotifywait -t 10 ...; done)| \
while read dir file event
do
#something
done &
kill "$!" # kill the while loop
None of this solution are nice. What is your real achievement? Maybe we can find a more elegant solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With