Milan Markovic Milan Markovic - 7 days ago 7
Linux Question

Two piped programs, one continues to run after another is killed

I have two programs piped in my bash script:

program1 | program2


The problem is that program2 can crash, and I want to make sure that when it does, program1 will end also. I tried to test this by killing program2 with

pkill program2


during execution, but the program1 continues to run.

As far as I understood, many people are asking how to make program1 continue to run because it is killed by default. Am I missing something?

Answer

Instead of using an anonymous pipe, use a named pipe that gives you more control over each end.

mkfifo p
program1 > p &  p1_pid=$!
program2 < p
kill "$p1_pid"

In this snippet, we create a named pipe called p, then run program1 in the background with its standard output redirected to p. p1_pid stores the process ID of program1 for later use. Note that program1 is started, but immediately blocks until something opens pfor eading. We runprogram2with its standard input redirected fromp`, then block while it runs.

When program2 exits for whatever reason, the kill command will send SIGTERM to program1 to kill it if necessary. This has two benefits:

  1. It can kill program1 more quickly, since you don't have to wait for program1 to write to the pipe and receive a SIGPIPE signal.

  2. If program1 is handling SIGPIPE, it may be handling other signals as well. You can use kill to send whatever signal is necessary (up to and including SIGKILL, if really necessary) to terminate the process.