Why does ps -ef | grep $$ shows the grep command in the process list? Isn't the grep executed after the ps is has finished his work?
1 Answer
When piping commands, all processes are started at the same time and they just sleep (block) until I/O enters/exits them. The shell does not buffer the output and hold it until one process has completed and then transfers it to another process.
For example:
mtak@rubiks:~$ tar -zcvf test.tgz /lib/ | grep bla | grep foo | grep bar Results in:
mtak 28813 28799 0 12:35 pts/17 00:00:00 tar -zcvf test.tgz /lib/ mtak 28814 28799 0 12:35 pts/17 00:00:00 grep --color=auto bla mtak 28815 28799 0 12:35 pts/17 00:00:00 grep --color=auto foo mtak 28816 28799 0 12:35 pts/17 00:00:00 grep --color=auto bar You can see the state of the grep process in the /proc tree:
mtak@rubiks:~$ grep State /proc/28814/status State: S (sleeping) You can also see that both greps are connected to the same pipeline (id 57573438) and that the STDOUT (1) of the first process is connected to the STDIN (0) of the second process.
root@rubiks:~# ls -l /proc/28815/fd total 0 lr-x------ 1 mtak mtak 64 dec 1 12:35 0 -> pipe:[57573437] l-wx------ 1 mtak mtak 64 dec 1 12:35 1 -> pipe:[57573438] lrwx------ 1 mtak mtak 64 dec 1 12:35 2 -> /dev/pts/17 root@rubiks:~# ls -l /proc/28816/fd total 0 lr-x------ 1 mtak mtak 64 dec 1 12:35 0 -> pipe:[57573438] lrwx------ 1 mtak mtak 64 dec 1 12:35 1 -> /dev/pts/17 lrwx------ 1 mtak mtak 64 dec 1 12:35 2 -> /dev/pts/17 4