3 ms·
I'm not sure whether you've understood the underlying ideas still. Peter's post on lobste.rs (https://lobste.rs/s/mb14bg/what_should_be_output_this_command_ech
by devnonymous 8y ago
I'm not sure whether you've understood the underlying ideas still.
Peter's post on lobste.rs (https://lobste.rs/s/mb14bg/what_should_be_output_this_command_echo#c_mjvjtk https://lobste.rs/s/mb14bg/what_should_be_output_this_comman... ) is far more comprehensive and clear imo, than any of the other explanations (including mine), but the idea is essentially the same.
* There is no blocking on buffers involved. The 2 ends of the pipe are simultaneously run. One in a subshell and one in the current shell.
* If the one in the current shell (right side of the pipe) is executed and finished first, blue is sent to the stderr (ie: the console), a SIGPIPE is sent to the subshell process (thus ensuring red is never printed) but if SIGPIPE is ack'd after echo green is sent to the stderr, you also see green, else you see only blue
* If the one in the subshell is executed first then red is sent to the stdout of the subshell (which is the pipe, but nobody is reading the pipe, so it just lies in there and eventually is lost, since the other end of the pipe will eventually be closed without any read()), green is sent to the stderr and then blue.
I feel you believe there subshell process is blocked because nothing is reading from the other side. This is incorrect. The pipe buffer will be written to until the "pipe size" (try ulimit -a or ulimit -p). The write end will not be blocked until then.
Some reading:
https://www.gnu.org/software/bash/manual/html_node/Command-Grouping.html#Command-Grouping
https://www.gnu.org/software/bash/manual/html_node/Command-Execution-Environment.html#Command-Execution-Environment
http://man7.org/linux/man-pages/man7/pipe.7.html (see I/O on pipes)
- devnonymous 8y agoI see you've now updated the post and got the idea. Small nitpick tho'. > When the right side of the pipe ends, the shell kills the left side. That's technically incorrect. The shell sends SIGPIPE to the subshell. SIGPIPE can be trapped/ignored (man trap) and although the default disposition is to kill the process that receives the signal, this might not be always true. For instance, what do you suppose would happen with this: (x=42; echo $x 1>&2 ) | echo blue versus: (trap '' PIPE; x=42; echo $x 1>&2 ) | echo blue in a loop ?