I thought that when i running below commands
sleep 10 | sleep 2 | sleep 5
Linux process will be
86014 ttys002 0:00.03 bash 86146 ttys002 0:00.00 sleep 10
when sleep 10
is end -> sleep 2
(when sleep 2 is end)-> sleep 5
that’s i thought
But in Linux bash sleep 10, sleep 2, sleep 5
are in ps
same time
Standard output of sleep 10
process will be redirected to sleep 5
‘s process
But, in that case, sleep 5
‘s process will be finished before sleep 10
I’m confused, any google keywords or concepts of that phenomenon?
(I’m not good at English, maybe it’s hard to understand this text🥲. Thank you)
Advertisement
Answer
I think you expect the commands to be run in sequence. But that is not what a pipe does.
To run two commands in sequence you use the ;
, what it is called a command list, I think:
$ time ( sleep 1 ; sleep 2 ) real 0m3.004s
You can also do command lists with &&
(or ||
) so that the sequence is interrupted if one command returns failure (or success).
But when you run two commands with |
both are run in parallel, and the stdout
of the first is connected to the stdin
of the second. That way, the pipe acts as a synchronization object:
- If the second command is faster and empties the pipe, when it reads it will wait for more data
- If the first command is faster and writes too much data to the pipe, its buffer will fill up and it will block until some data is read.
- Additionally, if the second command dies, as soon as the first one writes to
stdout
it will get aSIGPIPE
, and possibly die.
(Note what would happen if your programs were not run concurrently: your first program could write megabytes of text to stdout
, and with nobody to read it, the pipe would overflow!)
But since sleep
does not read or write to the console, when you do sleep 1 | sleep 2
nothing special happens and both are run concurrently.
The same happens with 3 or any other number of commands in your pipe.
The net effect is that the full sleep is the longest:
$ time ( sleep 1 | sleep 2 | sleep 3 | sleep 4 ) real 0m4.004s