1

I don't understand the following:

mkfifo p; $ (>p ps -f | >>p echo $BASHPID) & [1] 983527 $ cat p 983529 PID PPID C STIME TTY TIME CMD 981815 165343 0 19:57 pts/27 00:00:00 bash 983527 981815 0 21:09 pts/27 00:00:00 bash # <- child bash process `(...)` 983528 983527 0 21:09 pts/27 00:00:00 ps -f 983530 981815 0 21:09 pts/27 00:00:00 cat p 

(...) & results in a child process with PID 983527. It is a bash process.

ps -f executes in a child process of (...) with PID 983528. It is the left hand-side component command of the pipeline ...|....

echo $BASHPID reports to be executing in a process with PID 983529. It ought to be the right hand-side component of the pipeline ...|... and it ought to be listed as a bash process.

Is that last interpretation correct? And why can we not see that last process listed by the ps -f command?

1 Answer 1

1

>p ps -f | >>p echo $BASHPID in bash starts two child processes at the same time, connected by a pipe. Both processes start with opening the p fifo in write-only mode (with the O_APPEND flag for the second one, but that has no effect on a pipe).

As that fifo has no reader yet, both open()s will hang there waiting for some process to open the fifo in read mode.

So at that point, you have those two processes in the starting blocks.

The left one still has to execute ps which means finding and loading the /bin/ps executable, loading the dynamic linker, loading and linking libraries, start reading /proc, etc, a lot of work. While all the right one has to do is expand $BASHPID, perform split+glob on it, invoke the echo builtin (just invoke an internal function) which just writes that expansion and exit.

Upon running cat p, as soon as cat opens the fifo, both processes above will be unblocked at the same time. The right (echo) one will likely have done its simple work and exited¹ long before ps has even finished loading, so ps will not find it in /proc which explains why you don't see it.


¹ and its death will have been acknowledged by its parent, otherwise the process would still show as a zombie

1
  • 1
    Oh I see... Indeed, running (>&2 ps -f | >p echo $BASHPID) & instead, which blocks only the right-hand side, allows the child bash process of the echo command to be listed in the output of ps. Thanks! Commented Nov 13, 2021 at 23:07

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.