How to get pid of piped command?

(or How to kill a child process)?

inotifywait -mqr --format '%w %f %e' $feedDir | while read dir file event
do
#something
done &

echo $! #5431

ps for example:

 >$ 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 that if I kill 5431 , then 5430 ( inotifywait ) will be started, but if I kill 5430 strong> then both processes die. I don’t think I can safely assume that pid inotifywait will always be 1 less than $! ?

+4
source share
2 answers

When we launch the channel, each command is executed in a separate process. The interpreter is waiting for the latter, but if we use ampersand (&).

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. , SIGPIPE ( ), . ... .

"$!" pid , . bash, while.

pid "inotifywait" . uggly:

(inotifywait ... & echo "$!">inotifywait.pid) | \
while read dir file event
do
    #something
done &
cat inotifywait.pid # prints pid of inotifywait

pid, , , -t inotifywait:

(while true; do inotifywait -t 10 ...; done)| \
while read dir file event
do
    #something
done &
kill "$!" # kill the while loop

. ? , .

+2

- , . BusyBox Ash, . fd, .

#!/bin/sh

pid=$$

terminate() {
  pkill -9 -P "$pid"
}

trap terminate SIGHUP SIGINT SIGQUIT SIGTERM

# do your stuff here, note: should be run in the background {{{
inotifywait -mqr --format '%w %f %e' $feedDir | while read dir file event
do
#something
done &
# }}}

# Either pkill -9 -P "$pid" here

wait

# or pkill -9 -P "$pid" here

:

kill <pid ($$)>
0

Source: https://habr.com/ru/post/1540274/


All Articles