Bash

具有自己的 $BASHPID 的子shell(子程序/子程序)未由 ps 列出

  • November 13, 2021

我不明白以下內容:

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

(...) &產生一個 PID 為 983527 的子程序。它是一個 bash 程序。

ps -f在 PID 為 983528的子程序中執行。(...)它是管道的左側組件命令...|...

echo $BASHPID報告將在 PID 983529 的程序中執行。它應該是管道的右側組件,...|...並且應該被列為 bash 程序。

最後的解釋正確嗎?為什麼我們看不到ps -f命令​​列出的最後一個程序?

>p ps -f | >>p echo $BASHPIDinbash同時啟動兩個子程序,通過管道連接。兩個程序都以只寫模式打開pfifo 開始(帶有O_APPEND第二個標誌,但這對管道沒有影響)。

由於該 fifo 還沒有讀取器,因此兩個open()s 都會掛在那裡等待某個程序以讀取模式打開 fifo。

所以到那時,你有這兩個過程在起點。

左邊的仍然需要執行ps,這意味著查找和載入/bin/ps執行檔、載入動態連結器、載入和連結庫、開始閱讀/proc等大量工作。雖然所有正確的事情要做的是 expand $BASHPID,對其執行 split+glob,呼叫echo內置函式(只是呼叫一個內部函式),它只是編寫該擴展並退出。

執行cat p時,只要cat打開fifo,上面的兩個程序就會同時被解除阻塞。正確的 ( ) 很可能已經完成了簡單的工作並在載入完成echo之前很久就退出了¹ ,因此找不到它來解釋為什麼您看不到它。ps``ps``/proc


¹ 並且它的死亡將得到其父級的承認,否則該程序仍將顯示為殭屍

引用自:https://unix.stackexchange.com/questions/677410