I have a small script to demonstrate what I want to do

> z
tail -f z | grep 'd' &
echo $!

The $! gives the PID of the grep process. I want to be able to kill the tail process at the same time as killing the grep process. Doing kill "pid of grep"does not kill the tail process. Nor does killall grep. I could use killall tail but I think this would be dangerous.


Enclose your command with parentheses:

( tail -f z | grep 'd' ) &
kill -- -$!

This will kill the whole sub-process.

Here, by specifying a negative PID to kill, we kill the whole process group. See man 1 kill:

Negative PID values may be used to choose whole process groups; see the PGID column in ps command output.

Or man 2 kill:

If pid is less than -1, then sig is sent to every process in the process group whose ID is -pid.

However, kill -PID will only work if job control is enabled in bash (the default for interactive shells). Else, your subprocess won't have a dedicated process group and the kill command will fail with kill: (-PID) - No such process

To work around that, either activate job control in bash (set -m), or use pkill -P $!

  • This doesn't seem to work. I executed this script and echoed the $!. Then I killed the process and appended "r", then "d". But the grep was still running and it echoed the "d" to stdout. Furthermore, killing that pid still shows the tail and grep in ps ux – user1005909 Jan 12 '17 at 15:21
  • @user1005909 Sorry, I answered too quickly. Answer updated – xhienne Jan 12 '17 at 15:24
  • 1
    Looks like there's an extra - on -$!. Anyway, this works only if the kill statement is in the bash script. Echoing the pid, then using kill -- pid from another shell doesn't work. – user1005909 Jan 12 '17 at 15:27
  • 1
    I see. I was getting -bash: kill: (-pid) - No such process. But this lead me to use pkill -P pid which works as I want. – user1005909 Jan 12 '17 at 15:36
  • 1
    @user1005909 That's weird. I have never had any issue with the command kill -- -PID. I've just tried it again with Debian, Ubuntu and SLES, and it works fine. – xhienne Jan 12 '17 at 15:42

I tried this and it didn't work for me

( tail -f z | grep 'd' ) &
kill -- -$!

I just used a named pipe instead of an unnamed pipe

rm -f tailfifo; mkfifo tailfifo
tail -n 0 -f mylog.log >tailfifo &
grep --line-buffered someword <tailfifo >outputfile &
# .. ..
kill $TAIL_PID
kill $GREP_PID
  • 1
    You tried what?  The other answer?  If you refer to another answer, please say so clearly. – G-Man Jul 25 '18 at 23:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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