単純な猫エコプロセスの交換は中止されます。

単純な猫エコプロセスの交換は中止されます。

catを使った簡単なプロセスの交換が中断されたようです。

cat >( echo hello; )

決して終わりません。また試しました:

cat >( echo hello; exit; )

子プロセスでstdoutファイルの説明を手動で閉じても機能しません。

cat >( echo hello; 1>&- )
cat >( echo hello; 1>&- exit; )

私はGNU bashバージョン4.4.23(1)-リリース、GNU bash、バージョン4.1.2(2)-リリースとzsh 5.5.1(x86_64-debian-linux-gnu)を試しました。

なぜこれが起こるのか説明できますか?私はプロセスの置き換えが大好きです...

ありがとう

編集:catがechoから読み取られた場合、プロセス置換の正しいリダイレクトは次のとおりです。

cat <( echo hello; )

答え1

あなたのコードは決してcat >( echo hola; )終了しません。

  • まずパターンをエコーし​​ます。hola
  • 書き込みのための入力を受け入れます。
  • 私たちがそれを与えると、書き込むCtrl+Dファイルを検索し続けます。

オプション1:エコーされたファイルへのコンテキストの書き込み

cat > $( echo hola; )

したがって、以下に提供するすべてのコンテキストはhola

注:次のようにcatブロックを終了できます。Ctrl+D

オプション2:エコーされたコンテキストをキャプチャします。

cat <(echo hola;)

答え2

何を達成したいのか分からないが、

  1. >(...)実行中のすべての項目の標準入力を書き込み可能にします。
  2. cat読み取り可能なファイルが必要です。

(1) が提供する内容を読むことができるという保証はありません。 macOSではエラーが発生しました。

bash-4.4$ cat >( echo foo)
foo
cat: /dev/fd/63: Permission denied

Linuxでは、もう一方の端に何も書かれていないパイプです。

$ strace -e openat cat >(echo foo)
foo
...
openat(AT_FDCWD, "/dev/fd/63", O_RDONLY) = 3

そして:

$ ll /proc/$(pgrep cat)/fd/3
lr-x------ 1 muru muru 64 Aug 13 18:55 /proc/3381/fd/3 -> 'pipe:[37501]'
$ lsof | grep 37501
strace    3433                 muru   63w     FIFO               0,12      0t0      37501 pipe
cat       3435                 muru    3r     FIFO               0,12      0t0      37501 pipe
cat       3435                 muru   63w     FIFO               0,12      0t0      37501 pipe

もう一方の端がstdinを閉じて終了することは重要ではありません。パイプを開くだけです。読む、何も記録されず、パイプにも何も記録されません。それでcatそこに置いて読書が完了するのを待ちます。 (ここstracecat ここは両方ともパイプに書き込むために開いているファイルハンドルを持っていますが、これはbashが書き込みのためにファイルハンドルを開いて使用できるようにしたためです。どちらも書き込めません。)

答え3

プロセスの置き換えはそれ自体のトピックです。知っておくべき重要な点は、これがstdinやstdoutよりもFIFOに近いことです。 echoを使用してこれを確認できます。

echo >( echo hello; )

あなたに: /dev/fd/63 こんにちは

外部エコーは実際に与えられたパラメータを提供します/dev/fd/63。だからあなたの

cat >( echo hello; )

実際にcat /dev/fd/43出力はに送信されますecho hello。 (43は単なる例で、数字はランダムですが、通常63です。)

以下の違いも確認できます。

echo hop > >(cat)

これは提供hopします

echo hop  >(cat)

これは作るhop /dev/fd/63

また、例えば次のようになります。

 sed 's/$/klap/' | tee >(sed 's/^/hop/')

コメントを提示するklop

klopklap
hopklopklap

これはklopklap標準出力でありtee、プロセスで置き換えられた標準出力ですhopklopklapsed

それではなぜ停止しますかcat >(echo hello)?前述のように、catは引数を受け取り、/dev/fd/32その「ファイル」ではEOFを取得できないためです。

答え4

停止せずcatにユーザーの入力を待っています。cat標準入力を読み、標準出力に書き込みます。標準入力をリダイレクトしないため、標準入力は端末です。と入力するとCtrl+Dファイルの終わりを示し、ファイルがcat終了します。

関連情報