vinllen
vinllen

Reputation: 1459

what is the output of grep pipeline

I have a process named "gao", the "grep" of process display two processes including "awk".

ps aux | awk '/gao/{print}'

where the output has two lines while I just want one including "gao" only.

vinllen           1205 100.0  0.0  2432780    652 s005  R+   12:01PM   0:14.80 ./gao
vinllen           1271   0.0  0.0  2423460    232 s006  R+   12:01PM   0:00.00 awk /gao/{print}

So I want to insert "grep -v awk" into this shell script. But I don't know which place should I do. After trying to insert this sentence after "ps aux", it works.

vinllen@ ~/code/tmp/2017_07_17$ ps aux | grep -v awk | awk '/gao/{print}'
vinllen           1205 100.0  0.0  2432780    652 s005  R+   12:01PM   2:39.12 ./gao

This confused me a lot, because in my understanding, the first "ps aux " pipeline will output all the processes, the second "ps aux | grep -v awk" will output all the processes excluding "awk", and the second pipeline will raise a process with "awk" again. So I think there should be two processes either like following:

vinllen           1205 100.0  0.0  2432780    652 s005  R+   12:01PM   0:14.80 ./gao
vinllen           1271   0.0  0.0  2423460    232 s006  R+   12:01PM   0:00.00 awk /gao/{print}

Could anyone tell me why? Thanks a lot.

Upvotes: 0

Views: 365

Answers (2)

perreal
perreal

Reputation: 97938

You can use pgrep to grep processes:

ps u $(pgrep -f gao)

Upvotes: 1

Ed Morton
Ed Morton

Reputation: 203284

When you ask the shell to execute a chain of commands in a pipeline the shell creates the pipeline and then starts each command in that pipeline in whatever order it sees fit to start them. So given this pipeline:

A | B | C

the pipeline will be created and then the process created in the order B, A, C or C, B, A or some other order. If B requires output from A to do something then B will block waiting for A to produce output so in that regard the order in which each tool receives input and produces output is determined by the order they appear in the pipeline but what is NOT guaranteed is that the processes will be created in the order they appear in the pipeline, i.e. A then B then C.

So if you have

ps aux | grep -v awk | awk '/gao/{print}'

then the shell might start awk after it starts ps and so if that happens then the string awk will not even appear in the ps output being fed to grep. On the other hand the shell might start awk before it starts ps and then the string awk will appear in the ps output but then be removed by grep. So either way you're not going to see awk in the output of that pipeline.

btw you never need grep when you're using awk and print is awks default behavior so you could write that pipeline as just:

ps aux | awk '!/awk/ && /gao/'

Whether you use grep or just stick to awk this approach is fragile of course due to the potential for partial matching or matching in the wrong part of the ps output so look into using pgrep instead.

Upvotes: 4

Related Questions