Ps command and grep
Sophia Terry
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 barResults 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 barYou 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