Reputation: 1459
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
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