これは次の質問です: `... | sed 's/^/stdout:/'`が `...>>(sed 's/^/stdout:/ ') `はしませんか?
より具体的には、なぜこれがパイプなのか:
$ tee 2> >(readlink /proc/self/fd/1) < /dev/null | cat
pipe:[17955449]
これが端末デバイスの場合:
$ tee >(readlink /proc/self/fd/1) < /dev/null | cat
/dev/pts/31
前者の出力も、コマンドを入力しているシェルから継承された端末であると自然に思っていたでしょうが、bashとzshの両方が、コマンドの出力にリダイレクトするために明示的な手順を実行する必要があるようです。リダイレクトしています。なぜ彼らはそれをしているのですか?または何か他のことが起こっていますか?前者のサブシェルは、tee
'ing exec
の前にtee
のプロセスから生成されますか?一方のサブシェルは子プロセスから継承し、もう一方は親プロセスから継承しますか?どうやって?
うーん...タグを付けてbash
をチェックしていると、どちらの場合もbashのパイプであることがわかります...つまり、これはzshの特性です。
zshは、同じコマンドの複数のリダイレクトをサポートします。たとえば、abc > def > ghi
は、abc
の完全な出力をdef
とghi
の両方に入れます。また、>
と1つの装飾されていない|
リダイレクトの両方を一度に許可します。これは、最初の例で使用しているものです。
その複数のリダイレクトの状況では、それにリダイレクトを伴うプロセス置換
tee 2> >(readlink /proc/self/fd/1) < /dev/null | cat
メインコマンドと同様に出力がパイプ処理され、リダイレクトなしのプロセス置換が行われます。
tee >(readlink /proc/self/fd/1) < /dev/null | cat
そうではありません。パイプはある意味で優先されます。リダイレクトのブランチからのすべての出力は、パイプを通過します。この場合、2つのブランチ(メインコマンド自体とプロセス置換からの出力)があり、どちらもcat
を通過するため、どちらも標準出力をパイプとして認識します。
Bashは常にcat
に置換をパイプし、そもそもそのような複数のリダイレクトをサポートしていません。
本質的に、zshに複数のリダイレクトがある場合でも、|
は1つしか存在できず、パイプはすべてのブランチに分散しますリダイレクトですが、プロセス置換自体はその一部ではありません->
を使用した実際の出力リダイレクトのみ。
これはリダイレクトのプロパティであり、プロセス置換によって表示されます。リダイレクトされたプロセスとリダイレクトされていないプロセスの両方を一緒に使用すると、次のことがわかります。
$ true >( readlink /proc/self/fd/1 ) > >( readlink /proc/self/fd/1 ) | cat
/dev/tty1
pipe:[2975]
最初のもの(単なる置換)にはTTYがstdoutとしてあり、2番目(リダイレクト先)にはcat
へのパイプがあります。これは、そのセットアップを構築する唯一の簡単な方法です。pipeed-toコマンドの単一インスタンスと、その前のpipeedコマンドとunpipedコマンドの混合です。望まないときに出力をリダイレクトする間違ったトラックになってしまった場合は、> /dev/pts/...
で回復できますが、Bashのようにベア置換をリダイレクトしたい場合は、まだ運が悪いです。
プロセス置換はそれ自体でシェルから環境を継承しますが、リダイレクトはパイプ内の入力と出力の両方と要素を変更します。このように機能するのは必要ではないと思いますが、一貫したルールがあります:|
は常に>
に分散しますが、引数は無視します。
実際の動作が何であるかを示す私の実験は、ここにインラインで含めるには長すぎて扱いにくいですが、 この回答の改訂履歴では です。以下に、4つの異なるケース(>
と|
のそれぞれはい/いいえ)とそれらの動作を要約します。
全体として、zshの動作には4つの異なるケースがあります。
|
、いいえ>
abc >( def ) | ghi
これは、ベースコマンドの出力をパイプに、サブシェルの出力をTTYに送信し、abc
へのパスを渡します。
|
なし、>
なし
abc >( def )
これにより、すべてがTTYに送信され、パスがabc
に渡されます。
|
はありませんが、>
abc > >( def )
これにより、ベースコマンドの出力はサブシェルにのみ送信され、サブシェルはTTYに送信されます。abc
には引数を指定しません。
|
および>
abc > >( def ) | ghi
これは、ベースコマンドの出力をbothプロセス置換とパイプに送信し、サブシェルの出力をパイプに送信します。abc
には引数を指定しません。 abc | tee >( def ) | ghi
として機能します。
変更がパイプから遠く離れているように感じる場合、ケース4がケース1とそれほど異なることはあまり好きではありませんが、それはそうです。