私は両方のアプローチを見て、<<<'foo'
それを<(echo 'foo')
エコパイプ()の代わりとして提案しましたecho foo | cat
。
catでこれら2つの構造を使用すると、次のような結果が得られます。
$ cat <<<'foo'
foo
$ cat <(echo 'foo')
foo
これまでもそうです。
しかし、シェルで直接使用すると、違いが明らかになります。
$ <<<'foo'
foo
$ <(echo 'foo')
zsh: permission denied: /dev/fd/12
私はzshを使用していますが、bashは<<<
この場合を別の方法で処理しているようです。何も印刷せず、この場合zshと同じです<()
。
しかし、実際に私の質問を提起することは1つの違いです。
$ diff <<<"/mypath" <(pwd)
diff: missing operand after `/dev/fd/63'
diff: Try `diff --help' for more information.
これら2つのタイプのシェルリダイレクトの間には根本的な違いがあることは明らかです。誰でも違いを説明できますか?
ベストアンサー1
<<< text
コマンドのファイル記述子に影響を与えるのはリダイレクトです(ここでは0ですが4<<< text
fd 4には影響します)。
whileは<(...)
リダイレクトではなく拡張/代替です。ファイル名に展開されます。コマンドに挿入すると、コマンドに渡されるパラメーターに影響します。
cat <(echo test)
cat
引数に似たファイルを使用して実行します/dev/fd/12
。そしてfd 12はパイプの読み出し端でも開いています。cat
fd 12では読みませんが、ファイルを開くと、/dev/fd/12
fd 12と同じパイプを指す新しいfd(おそらく3)が得られます。
echo test
バックグラウンドで実行されている間、fd 1は同じパイプの書き込み端に接続されているため、echo
最終的にはcat
そのパイプを介して接続されます(通信チャネルはそれを設定するよりも複雑ですがecho text | cat
)。
cat <<< text
引数なしでcatを実行し、fd 0を開きますtest\n
。
zsh 説明
<<< test
〜のように
$NULLCMD <<< test
これは、リダイレクトのみを含むエントリを実行するたびに($NULLCMD
通常は)発生します(リダイレクトがcat
1つしかない場合(通常はポケットベル)が使用されない限り)。<
$READNULLCMD
存在する:
<(echo text)
リダイレクトはなく、単にプロセスオーバーライドがあり、/ dev / fd / 12パラメータに拡張されます。これはシェルにファイルを実行するように要求します。
zshでは、以下を使用しても実質的な利点はありません。
cat <(echo test)
cat < <(echo test)
超過
echo test | cat
Bashなどの他のシェルでこの構成を表示できます。たとえば、次のようになります。
IFS= read -r var < <(echo text)
しかし、その理由は、そのシェルでは子プロセスで実行されるecho text | IFS= read -r var
ため、機能しないためです。read
そうではありませんzsh
。
プロセス置換は、標準入力ではなくファイル名を介した入力のみを引数として受け入れるコマンドとdiff <(cmd1) <(cmd2)
。
とのzsh
間の1つの違いは、後者が待たないということです。両方のシャットダウン状態が使用可能になっている場合にのみ待機して入ります。と比較されます。cmd1 | cmd2
cmd2 < <(cmd1)
zsh
cmd1
cmd1
cmd2
cmd1 | cmd2
$pipestatus
sleep 1 | uname
uname < <(sleep 1)
cmd <<< foo
cmd
入力を見つける必要がある場合に便利です(zsh
ここでは、ドキュメントなどの文字列はパイプではなく一時ファイルを使用して実装されるためです)。