When is the piped program terminated and who controls this termination process? I've read Bash: why the pipe is terminated? but it covers this question only partially. After trying to answer this question myself I made a couple of examples to see their outputs. And this one I don't understand: (a.sh
):
#!/bin/bash
echoerr() { echo $@ 1>&2; }
echoerr a.sh started
sleep 1
echo 1
sleep 1
echo 2
sleep 1
echo 3
sleep 1 # Line 1
echo 4 # Line 2
echoerr a.sh finished
And I run it as ./a.sh | head -3
. The output is:
a.sh started
1
2
3
From the output I understood that ./a.sh
was terminated with SIGPIPE
signal after reading first 3 lines of input because no more data was needed. But when I remove either Line 1 either Line 2 the output changes to the following:
a.sh started
1
2
3
a.sh finished
So my question are:
As you've said, you shell script will die if it attempts to write to a closed pipe. It won't if it doesn't.
If you remove the second line, a.sh
doesn't attempt to write to its stdout
after echo 3
, so it has no reason to fail.
Removing the first line might not get you the same result every time you run your test. There's a timing issue. If the last two echo
statements are processed before head
attempts to read from it's input (and terminate because it's reached 3 lines), then a.sh
won't get a broken pipe error. If the timing is such that head
does a read in between the two echo
s, then a.sh
will get the pipe error, and die.