はじめに

bashのプロセス置換は、引数でファイルを指定すべきところをコマンドの結果で代用できる機能。コマンドの結果をファイルとして扱え、作業用の中間ファイルを作る必要がなくなる。

記述方法 内容
<(コマンドリスト) コマンドの結果をファイルとして扱う
>(コマンドリスト) 出力先をコマンドに渡す

<(コマンドリスト)

プロセス置換の利用例としてよく挙げられるものに、ファイルの比較を行うdiffの引数にファイルの代わりにコマンドを渡すがある。

diff <(command_list) <(command_list)

filenameで始まる名前のファイルが大量にあるとして、原則、ファイルには特定の文字列「something」が入っているとする。somethingが入っていないファイルを探したい。

$ diff <(grep something filename* -l | xargs ls -t) <(ls -t filename*)
0a1,3
> filename9
> filename8
> filename7

grep -lで出力したファイル名と、lsで出力したファイル名をdiffに渡している。

>(コマンドリスト)

「出力先をコマンドに渡す」という仕組みから、多くの場合パイプで代替できるため使用頻度は高くない。 通常はパイプで行うが、可読性の面からプロセス置換の方がよさそうなものに、「標準エラー出力にパイプをつなぐ」というのものがある。

標準エラー出力をパイプをつなぐ方法はcommand 2>&1 1>/dev/null | commandでいいのだがプロセス置換でも実現できる。リダイレクトが複数ある場合、右側にある方から評価される。書き順を間違いやすいため注意が必要。普段よく書く「すべてを/dev/nullに捨てる」command >/dev/null 2>&1はイディオム的に覚えているのだが、これも評価順をよく考えると、右から2>&1で標準エラー出力を標準出力に統合し、その次に>/dev/nullで標準出力を捨てている。

# NG
$ ls test.txt 1>/dev/null 2>&1 | grep -o No

# OK
$ ls test.txt 2>&1 1>/dev/null | grep -o No
No

# プロセス置換版
$ ls test.txt 2> >(grep -o No) 1>/dev/null
No

プロセス置換で書いた方が、それぞれの出力に対する操作が直後に来ているため、若干可読性がいいのではないか。

プロセス置換利用時の注意点

シェルスクリプトを書く場合、/bin/shにはプロセス置換がないため、shコマンドではなくbashコマンドを利用する。

$ bash shellscriptname

あるいは実行権限をつけて、./スクリプト名かフルパスでの実行であれば、shebangに#!/bin/bashが指定されていれば、bashで実行されるため問題ない。