私の考えでは標準出力を複数のコマンドに送信するしかし、プロセスの置き換えからstdinを読む方法がわかりません。
私の試み:
$ echo foo >(cat /dev/stdin) >(cat /dev/stdin)
foo /dev/fd/63 /dev/fd/62
$ echo foo >(cat -) >(cat -)
foo /dev/fd/63 /dev/fd/62
$ echo foo >(cat <&3) >(cat <&3) 3<&0
foo /dev/fd/63 /dev/fd/62
-bash: 3: Bad file descriptor
-bash: 3: Bad file descriptor
同じ問題の代替バージョン:
$ cat file | tee &>/dev/null >(cmd1 /dev/stdin) >(cmd2 /dev/stdin)
これを行う正しい方法は何ですか?
答え1
これは標準入力から読み取られます。
echo foo | tee >(read line </dev/stdin; echo "internal $line")
プロセスの置き換えはファイルと同じように動作することを覚えておく必要があります。
ファイルが必要な場所ならどこでも使用できます。 teeコマンドはファイルに書き込むことを期待しています。
このコマンドは、/dev/stdinから読み取るデバイスを指定します。この簡単な例では、/dev/stdin を削除でき、次のように動作します。
echo foo | tee >(read line; echo "internal $line")
あなたの要件を正しく理解すると、次のように動作します。
$ echo foo | tee >(read a </dev/stdin; echo "a is $a") \
>(read b </dev/stdin; echo "b is $b") \
>(read c </dev/stdin; echo "c is $c")
foo
a is foo
c is foo
b is foo
混乱を減らすためにPS2プロンプトを省略しました。各プロセスの置き換えは、ファイルの使用を置き換えます(例tee FILE FILE ....
::)。
読み取りが最初のコマンドである必要はありません。
$ echo foo > >(echo "hello" | read b; read a </dev/stdin; echo "a is $a")
a is foo
ここで、「プロセスの置き換え」にはリダイレクトが必要なので、
これら2つのイディオムが使用されます> >(
。
単純なエコーは、使用されたfdの番号(ファイル名)のみを印刷します。
$ echo >(echo "hello")
/dev/fd/63
hello
これは次のようになります。
$ echo "$file"
filename
しかし、これは非常に異なる慣用語です。
$ echo > "$file"