Quantcast
Channel: Bashタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 2811

プロセス(コマンド)の実行をファイルとして他のプロセスと連携する

$
0
0

Process Substitution

GNU Bash Manual 3.5.6 Process Substitution

>(list)

プロセスをファイルとして、そこに他のstdout/stderrをファイルとして書き出せる。

$ cat <<EOF > >(grep -v b)
> a
> b
> c
> EOF
a
c
  1. grep -v bがasyncに実行され、/dev/fd/xxx (xxxは番号)のファイルとして待ち構えている (async)
  2. catのstdoutをファイル( >(...)で実行されているプロセス)にリダイレクト
  3. catからリダイレクトされた3行がファイル = "grepのプロセス"に書き込まれる
  4. b以外のacがgrepのプロセスによって出力される

run_app.sh 2> >(tee log)のようにすれば、run_app.shのプロセスのstdoutはそのまま出力され、stderrをteeプロセスに書き込みながらlogにも保存できる。
run_app.sh実行時はerror yyy(stderr)、info xxx(stdout)の順のだとしても、run_app.shのstdoutとteeのstdoutは出力順が前後することがあるのは、process substitutionで実行されたプロセスはasyncに実行されるため。

<(list)

プロセスのstdout/stderrをファイルとして、そのファイルを他のコマンドの引数にできる。

$ A="a
b
c"
$ B="a
x
c"
$ diff -u <(echo "$A") <(echo "$B")
--- /dev/fd/63  2020-09-26 07:12:48.000000000 +0900
+++ /dev/fd/62  2020-09-26 07:12:48.000000000 +0900
@@ -1,3 +1,3 @@
 a
-b
+x
 c

結果からわかるようにecho "$A"の出力が/dev/fd/63というファイルとして保存され、そのファイルをdiffの1つ目のファイルとしている。
<(...)で実行されるプロセスが重い場合、ファイルのEOF = プロセスの終了まで読むのでブロッキングが発生する。複数の<(...)を一度に実行(上のdiffはその例)してもすべてasyncに実行されるので待ちの最大は一番重いプロセスの実行時間となる。

Note

  • < (とスペースを空けるとsyntax error (そりゃそうだ。redirectionじゃない。)
  • multilinesのvariableに対し、echo $Aecho "$A"の違いにつまずきがち

Viewing all articles
Browse latest Browse all 2811

Trending Articles