「ps」コマンドを使用すると、「cat /tmp/out1> /tmp/in2 &」が「bash」として表示されるのはなぜですか?

「ps」コマンドを使用すると、「cat /tmp/out1> /tmp/in2 &」が「bash」として表示されるのはなぜですか?

考慮する:

mkfifo /tmp/out1
mkfifo /tmp/in2
cat /tmp/out1 > /tmp/in2 &

私が走るとき

ps 

これはリソースセクションbashに示されているものと同じですCMD

なぜ?

答え1

psリスト強く打つ/tmp/in2コマンドを生成するcat前にfifoを開こうとするbashプロセスがブロックされているため、実行中のプロセスとして認識されます。bashこれはリダイレクト()処理を担当するため、後でシステムコールを使用してコマンドのファイル記述子をに変更できるようにするには、> /tmp/in2まず開く必要があります。残念ながら、この場合、呼び出しはブロックされます。/tmp/in2dup2STDOUTcat/tmp/in2open

strace でコマンドを実行するには、次のようにします。

strace -f bash -c "cat /tmp/out1 > /tmp/in2"

次の場所で停止していることがわかります。

[pid 18457] open("/tmp/in2", O_WRONLY|O_CREAT|O_TRUNC, 0666

他のプロセスが読み取るためにファイルを開くまでブロックされます。 ~によると先入選出(7)マニュアルページ:

カーネルは、1 つ以上のプロセスで開かれた各 FIFO 特殊ファイルのパイプオブジェクトを維持します。データを転送するには、まずFIFO(読み取りと書き込み)の両方を開く必要があります。通常、もう一方の端も開くまでFIFOブロックを開きます。

プロセスは、非ブロックモードでFIFOを開くことができます。この場合、読み取り専用で開くことは、誰かがまだ書き込み側で開いていなくても成功します。

最初に読み取りをオンにすると/tmp/in2(たとえば、最後のcatコマンドの前に追加する場合)、プロセスツリーにcat /tmp/in2 &最終コマンドが表示されます。cat

関連情報