On Sat, Apr 16, 2022 at 08:07:09AM -0400, The Wanderer wrote: > ...Huh. That's so unintuitive that it hadn't even occurred to me to test > it before posting, but I just did test it (with 'ps', not 'foobar', > because there's a reason why 'ps' would be special for this purpose), > and you're correct. > > I *think* it makes sense on examination? In that the fact that the first > grep command occurs in the ps output in the first place must mean that > its process is in some sense started before the ps command is run, even > though the ps command comes earlier in the pipeline, so the same must > logically hold true for the *second* grep command as well.
All of the commands in a pipeline are executed simultaneously, in parallel. Except of course nothing is truly simultaneous. The shell will attempt to start them all at roughly the same time, but individual timing issues across three child processes cause what we call a "race condition". Sometimes, one of them runs a bit too fast, or a bit too slow, and you get weird results. For this pipeline, ps -ef | grep foobar | grep -v grep the race condition is that the ps command could execute so quickly that the 'grep foobar' process hasn't even started yet. And then, you would *not* see 'grep foobar' in the output of ps, and so the final 'grep -v grep' wouldn't match any lines. In practice, you might not ever see this happen, at least not in a small number of trials. But if you do this thousands of times, on systems with varying loads, you might. And of course, tomas raised the excellent point that this is not the best way to show a process when you already know its PID. ps -ef | grep "$mypid" is silly. You can simply do ps -fp "$mypid" instead. You even get to see the headers, which are lost in the silly variant.