web-dev-qa-db-ja.com

「<(cmd)」パターンはbashでどのように機能しますか?

Bashでは、次のような引数を使用します

_paste <(cat file1 | sort) <(cat file2 | sort)
_

または

_comm <(cat file1 | sort) <(cat file2 | sort)
_

_man comm_または_man paste_をチェックすると、ドキュメントには、argsが実際にFILESであると記載されています。

質問:

  1. 中間の一時ファイルは<(cat file1 | sort)および<(cat file2 | sort)に対して(TEMPファイルシステムまたは低速ディスク上の他の場所に)作成されますか?

  2. この<( )マジックの名前は何ですか? (そのドキュメントを検索するため)

  3. それはbashに固有ですか、それとも他のシェルで機能しますか?

11
Thamme Gowda

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

.5.6プロセス置換

プロセスの置換により、ファイル名を使用してプロセスの入力または出力を参照できます。

プロセスリストは非同期で実行され、その入力または出力はファイル名として表示されます。このファイル名は、展開の結果として現在のコマンドに引数として渡されます。 >(リスト)フォームが使用されている場合、ファイルへの書き込みによりリストの入力が提供されます。 <(list)形式を使用する場合、引数として渡されたファイルを読み取って、listの出力を取得する必要があります。 <または>と左括弧の間にスペースを入れないでください。そうしないと、構成がリダイレクトとして解釈されます。プロセス置換は、名前付きパイプ(FIFO)または/ dev/fdメソッドでオープンファイルに名前を付けることをサポートするシステムでサポートされています。

これは、kshに最初に登場したbashだけではなく、posix標準にもありません。

内部的には、プロセス置換には2つの実装があります。 /dev/fdをサポートするシステム(ほとんどのUnixライクなシステム)では、pipe()システムコールを呼び出して機能します。これにより、新しい匿名パイプのファイル記述子$fdが返され、文字列が作成されます。 /dev/fd/$fd、そしてコマンドラインでそれを置き換えます。 /dev/fdサポートのないシステムでは、名前付きパイプを作成するために新しい一時ファイル名でmkfifoを呼び出し、コマンドラインでこのファイル名を置き換えます。

18
jesse_b

<( somecommand )は、somecommandの出力を含む一時ファイルのファイル名と考えることができます。言い換えると、

_utility < <( somecommand )
_

のショートカットです

_somecommand >tempfile
utility <tempfile
rm -f tempfile
_

そして

_utility <( somecommand )
_

のショートカットです

_somecommand >tempfile
utility tempfile  # notice the lack of redirection here (utility expected to read from "tempfile")
rm -f tempfile
_

同様に、>( somecommand )は、標準入力でsomecommandに供給される一時ファイルのファイル名と考えることができます。言い換えると、

_utility > >( somecommand )
_

のショートカットです

_utility >tempfile
somecommand <tempfile
rm -f tempfile
_

そして

_utility >( somecommand )
_

のショートカットかもしれない

_mkfifo temppipe
somecommand <temppipe &
utility temppipe  # utility is expected to write to "temppipe"
rm -f temppipe
_

(または類似の何か)

7
Kusalananda