Bash
為什麼“cat /tmp/out1 > /tmp/in2 &”使用“ps”命令顯示為“bash”?
考慮:
mkfifo /tmp/out1 mkfifo /tmp/in2 cat /tmp/out1 > /tmp/in2 &
當我跑
ps
它顯示
bash
在該CMD
部分中。為什麼?
ps
將bash列為正在執行的程序,因為 bash 程序在生成命令/tmp/in2
之前嘗試打開 fifo 被阻止。cat
由於bash
負責處理你的redirect(> /tmp/in2
),它必須首先打開/tmp/in2
,以便它以後可以使用dup2
系統呼叫將STDOUT
命令cat
的文件描述符更改為/tmp/in2
. 不幸的是,在這種情況下,呼叫open
被阻塞。如果要在 strace 中執行命令:
strace -f bash -c "cat /tmp/out1 > /tmp/in2"
你會看到它停在:
[pid 18457] open("/tmp/in2", O_WRONLY|O_CREAT|O_TRUNC, 0666
它被阻塞,直到另一個程序打開文件進行讀取。根據fifo(7)手冊頁:
對於至少由一個程序打開的每個 FIFO 特殊文件,核心只維護一個管道對象。FIFO 必須在兩端(讀取和寫入)都打開,才能傳遞數據。通常,打開 FIFO 會阻塞,直到另一端也打開。
程序可以在非阻塞模式下打開 FIFO。在這種情況下,即使沒有人在寫端打開只讀模式也會成功,除非另一端已經打開,否則只寫模式會因 ENXIO(沒有這樣的設備或地址)而失敗。
如果您
/tmp/in2
要先打開以供閱讀(例如cat /tmp/in2 &
在您的最終 cat 命令之前添加),您會看到您的最終cat
命令顯示在您的程序樹中。