This comment explains how programs terminate (or not) when the other end of the pipe gets closed:
Closing the pipe in
command1 does not tell
command2 anything at all. Nothing happens until
command2 reads the pipe, empties it, and gets an EOF. Even then, it does not have to exit if it has work still to do. Similarly, if
command2 exits first,
command1 does not find out about it until it writes to the pipe, at which point it receives
SIGPIPE. If it traps that, it too can carry on with other work.
So this is what can happen automatically. Now your question:
command1 | command2
How can I make it so that
command2 terminates when
command1 exits [even if
command2 doesn't notice or doesn't want to terminate]?
If your shell runs the pipeline in a separate process group, try to kill the entire group. E.g. Bash does this when job control is enabled (
set -m). It is enabled by default for interactive shells (on systems that support it), but not in scripts.
( command1; kill -s INT 0 ) | command2
The entire pipeline is run in a separate process group with PGID (process group ID) equal to the PID of the very first part, which in this case is a subshell.
kill 0 sends a signal to its own process group. This way we signal
command2 just after
- In Bash
kill is a builtin, so
kill in the example is not a separate process with PID and PGID assigned. Therefore the phrase "its own process group" above is not strict, it should be "the process group of the subshell". It's still the exact process group we want to use. The
kill builtin or
/bin/kill can be used, any will work.
command2 may change its own process group. If it does, the solution will not work.
- For almost all signals
command2 may ignore the signal or handle it in virtually any way. Choose a signal that fits your needs.
kill just after
command1 terminates may be too soon. It may cause
command2 to exit before it reads and handles all the data generated by
command1; and you may want it to handle all the data. Depending on how
command2 behaves, it may be useful to delay
sleep 2; kill …). Note that (general purpose) Linux is not a real-time operating system, so any fixed delay may turn out to be too short if the circumstances are bad enough.