System Administration & Network Administration
shell shell-scripting ps
Updated Tue, 19 Jul 2022 16:24:53 GMT

Why does `ps -x | grep foo` include the grep command?

I know that it does (often) include the grep process and I know adding | grep -v grep or grepping on [f]oo instead will prevent it, but my question is more about order of operations I guess.

For example, in this contrived example, I see several grep processes:

% ps -x | grep login | grep login | grep login | grep login
 2475 ??         0:00.03 /usr/libexec/loginitemregisterd
 2115 ttys004    0:00.04 login -fp jasonerickson
29715 ttys004    0:00.00 grep login
29716 ttys004    0:00.00 grep login
29717 ttys004    0:00.00 grep login
29718 ttys004    0:00.00 grep login

That tells me that ps -x must be executed last in that line, since it lists all of those subsequent grep commands. However, it is not consistent. Sometimes it will list 4 or 3 or 2 or even none of the grep processes. That would imply to me that it is not always last.

What's going on?


As Bravo points out, a pipe in Linux is not a file, it is dynamic. So ps -x | grep login will actually start both programs at once, so that one can pitch down the pipe and the other can catch. The reason it is not deterministic, why your contrived example doesn't always show four grep instances, is that an instance may not be started until there is something in the pipe for it to do; or the instance in question may not be fully started when ps reads the process list.