Ps command and grep

8

2

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?

Mulligan

Posted 2016-12-01T11:24:13.703

Reputation: 533

It's called pipeline... – Ipor Sircer – 2016-12-01T11:31:02.760

If it waited until the first command was finished, how would pipelines work with commands that don't stop on their own, like tail -f filename | grep pattern? – Barmar – 2016-12-02T17:33:52.007

Cross-site duplicate of In what order do piped commands run?

– Scott – 2016-12-06T21:14:33.130

Answers

11

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

mtak

Posted 2016-12-01T11:24:13.703

Reputation: 11 805

it's it a bit of a complex example though to say that they sleep and then to put in a sleep command 'cos then when it says sleep it's your sleep command rather than something being done by the shell – barlop – 2016-12-01T11:52:58.370

I just put the sleep command in there to introduce some delay so I could look around on the system. The sleep command does not impact the grep behind it, except that the grep does not receive any input. If it makes you happy, you can do the same thing with tar: $ tar -zcvf test.tgz /lib/ | grep foo | grep bar and then check the grep: $ cat status Name: grep State: S (sleeping) – mtak – 2016-12-01T11:57:03.350

Already edited it, so it's more clear. – mtak – 2016-12-01T12:00:24.517