bashの<()(およびzshの=())とは正確には何ですか?


36

私はbashにかなり満足していますが、最近、私は知らない交代で終わりました。

<(<command>)bash には正確には何がありますか?=(<command>)zsh と比較してどうですか?

これはデフォルトのファイル記述子と関係があることを理解しています。私のコンピューターで

echo <()

/proc/self/fd/11、スクリプトSTDOUTのコピーであることがわかりましたが、これはまだかなり混乱しているようです。

回答:


51

これはプロセス置換と呼ばれます。

<(list)構文は両方でサポートされている、されるbashzshlistパイプ(|)を使用できない場合に、コマンド()の出力を別のコマンドに渡す方法を提供します。たとえば、コマンドが単に入力をサポートしない場合、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)


これは、MacOS pfctl -f <(echo "pf rules")が不正なファイル記述子を言う理由を理解するのに役立ちました。代わりに、zshと=(echo "pf rules")を使用すると動作します。
johnnyB

9

これは、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)は<()プロセス置換構文の開始です。


2
zshの=(cmdlist)は、bashの<(cmdlist)とほぼ同じ効果がありますが、リダイレクト用のcmdlistの出力で一時ファイルを作成(および準備ができたら削除)します。これは、プログラムでシークが実行される可能性がある場合に便利です。<(cmdlist)もzshによって知られています。
ゴンバイサンドル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.