サーチ…
備考
プロセス置換は、プロセスの入力または出力(一連のコマンドのシーケンス)が一時ファイルとして表示されるリダイレクションの一種です。
ウェブから2つのファイルを比較する
以下では、一時ファイルを作成する代わりに、プロセス置換を使用してdiff
2つのファイルを比較します。
diff <(curl http://www.example.com/page1) <(curl http://www.example.com/page2)
コマンドの出力をwhileループに送ります
これはgrep
コマンドの出力をwhile
ループに送ります:
while IFS=":" read -r user _
do
# "$user" holds the username in /etc/passwd
done < <(grep "hello" /etc/passwd)
貼り付けコマンドで
# Process substitution with paste command is common
# To compare the contents of two directories
paste <( ls /path/to/directory1 ) <( ls /path/to/directory1 )
ファイルの連結
同じコマンドで入力と出力に同じファイルを使用することはできないことはよく知られています。例えば、
$ cat header.txt body.txt >body.txt
あなたがしたいことはしません。 cat
body.txt
までには、既にリダイレクトによって切り捨てられていて空です。最終的な結果は、 body.txt
がbody.txt
の内容だけを保持することにheader.txt
ます。
プロセスの置き換えでこれを回避すると考えるかもしれません。つまり、コマンド
$ cat header.txt <(cat body.txt) > body.txt
body.txt
の元の内容を、リダイレクトによってファイルが切り捨てられる前にどこかのバッファに保存するようbody.txt
します。それは動作しません。括弧内のcat
は、外側のファイル記述子と同様に、すべてのファイル記述子が設定された後にのみファイルの読み込みを開始します。この場合、プロセス置換を使用しようとしても意味がありません。
ファイルを別のファイルに追加する唯一の方法は、中間ファイルを作成することです。
$ cat header.txt body.txt >body.txt.new
$ mv body.txt.new body.txt
これは、 sed
またはperl
または同様のプログラムが、現場編集オプション(通常は-i
)で呼び出されたときにカーペットの下で行うことです。
複数のプログラムを一度にストリームする
これは、 gzip
圧縮しながら、大きなファイルの行数をwc -l
で数えます。どちらも同時に実行されます。
tee >(wc -l >&2) < bigfile | gzip > bigfile.gz
通常のtee
一個の以上のファイル(およびstdout)にその入力を書き込みます。私たちは、 tee >(command)
でファイルの代わりにコマンドに書き込むことができます。
ここで、コマンドwc -l >&2
は、 tee
から読み取られた行をカウントします(これは、 bigfile
からbigfile
)。 (行数は、標準エラー(に送られ>&2
への入力との混合を避けるために) gzip
。)のSTDOUT tee
同時にに供給されるgzip
。
サブシェルの使用を避けるには
プロセス置換の主要な側面の1つは、シェルからコマンドをパイプするときにサブシェルの使用を避けることができるということです。
これは以下の簡単な例で実証することができます。私は現在のフォルダに以下のファイルを持っています:
$ find . -maxdepth 1 -type f -print
foo bar zoo foobar foozoo barzoo
私がパイプをwhile
/ read
ループにパイプすると、次のようにカウンタがインクリメントされます。
count=0
find . -maxdepth 1 -type f -print | while IFS= read -r _; do
((count++))
done
$count
はサブシェルのコンテキストで変更されたため、現在は6
が含まれていません 。以下に示すコマンドはいずれもサブシェルコンテキストで実行され、サブシェル終了後に使用される変数のスコープは失われます。
command &
command | command
( command )
プロセスの代替は、パイプの使用を避けることによって問題を解決します|
オペレータ
count=0
while IFS= read -r _; do
((count++))
done < <(find . -maxdepth 1 -type f -print)
これは、サブシェルが呼び出されないので、 count
変数の値を保持します。