私はbashにかなり満足していますが、最近、私は知らない交代で終わりました。
<(<command>)
bash には正確には何がありますか?=(<command>)
zsh と比較してどうですか?
これはデフォルトのファイル記述子と関係があることを理解しています。私のコンピューターで
echo <()
は/proc/self/fd/11
、スクリプトSTDOUTのコピーであることがわかりましたが、これはまだかなり混乱しているようです。
私はbashにかなり満足していますが、最近、私は知らない交代で終わりました。
<(<command>)
bash には正確には何がありますか?=(<command>)
zsh と比較してどうですか?
これはデフォルトのファイル記述子と関係があることを理解しています。私のコンピューターで
echo <()
は/proc/self/fd/11
、スクリプトSTDOUTのコピーであることがわかりましたが、これはまだかなり混乱しているようです。
回答:
これはプロセス置換と呼ばれます。
<(list)
構文は両方でサポートされている、されるbash
とzsh
。list
パイプ(|
)を使用できない場合に、コマンド()の出力を別のコマンドに渡す方法を提供します。たとえば、コマンドが単に入力をサポートしない場合、STDIN
または複数のコマンドの出力が必要な場合:
diff <(ls dirA) <(ls dirB)
<(list)
の出力をlist
にあるファイルに接続します。/dev/fd
システムでサポートされている場合は、名前付きパイプ(FIFO)が使用されます(これもシステムのサポートに依存します。どちらのマニュアルも両方のメカニズムがサポートされない場合、エラー)。ファイルの名前は、コマンドラインの引数として渡されます。
zsh
の=(list)
可能な代替としてさらにサポートします<(list)
。=(list)
一時ファイルの代わりにファイルの使用されている/dev/fd
か、FIFO。<(list)
プログラムで出力を検索する必要がある場合の代替として使用できます。
ZSHマニュアルによると、動作方法には他の問題もある可能性があります<(list)
。
の名前付きパイプの実装には欠点
=
があるため、このフォームは便利です。前者の場合、特にプログラムがsetuidを実行しているときなどのセキュリティ上の理由で必要な場合、一部のプログラムはコマンドラインでファイルを調べる前に問題のファイル記述子を自動的に閉じることがあります。2番目のケースでは、プログラムが実際にファイルを開かない場合、パイプの読み取りまたは書き込みを試行するサブシェルは(通常の実装では、オペレーティングシステムごとに動作が異なる可能性があります)ブロックし、明示的に強制終了する必要があります。どちらの場合も、シェルは実際にパイプを使用して情報を提供するため、ファイルでlseek(manページを参照)を想定しているプログラムは機能しません。/dev/fd
<(...)
lseek(2)
これは、bshの回答であり、zshではないことに注意してください。
bashでパイプを使用できない場合があります。
some_command | some_other_command
パイプはパイプラインの各コンポーネントにサブシェルを導入するため、サブシェルが終了すると、依存していた副作用はなくなります。たとえば、次の不自然な例:
cat file | while read line; do ((count++)); done
echo $count
$count
変数が現在のシェルに存在しないため、空白行が表示されます。
bash プロセスの置換により、ファイルからのように「some_command」出力から読み取ることができるため、この難問を回避できます。
while read line; do ((count++)); done < <(cat file)
# ....................................1.2
echo $count # the variable *does* exist in the current shell
(1)は通常の入力リダイレクトです。(2)は<()
プロセス置換構文の開始です。
pfctl -f <(echo "pf rules")
が不正なファイル記述子を言う理由を理解するのに役立ちました。代わりに、zshと=(echo "pf rules")を使用すると動作します。