揮発性のメモ2

http://d.hatena.ne.jp/iww/

プログラムの標準出力を別のプログラムの標準入力に渡す

ようするにパイプなんだけど、普通と違う書き方ができる

$ ls -l | grep hoge
$ ls -l > >(grep hoge)

上の2つはだいたい同じような意味合いを持つ

io redirection - bash exec sending output to a pipe, how? - Stack Overflow
bash-hackers.org - このウェブサイトは販売用です! - bash hackers リソースおよび情報

Process substitution

プロセスの標準入力や標準出力を取得できる機能

<(command) がcommandの標準出力
>(command) がcommandの標準入力

$ echo <(ls)
/dev/fd/63
※ lsの標準出力のディスクリプタを表示

$ cat <(ls)
hoge.sh   piyo.txt
※ lsの標準出力を表示 = lsの結果を表示


この機能と bashのexec と組み合わせると、次のようなことをしたいときに一つのスクリプトにまとめることができる

$ ./hoge.sh | column -t

hoge.shの中に、次のようにexecを書くことができる

#!/bin/bash

# 後処理したいプログラムをProcess substitutionで起動
exec > >(column -t)
EXECPID=$!

# ここに本来の処理

# 後処理プログラムの終了を待つ
exec 1<&-
wait $EXECPID


最後にwaitを入れないと、columnの出力が出切る前に本体が終了してプロンプトが出てしまうことがあり、少々みっともない
(パイプならそんなこと起きないんだけど)
Process substitution 先では標準入力が閉じられるまでプログラムは動き続けるので、メインの方で標準出力を閉じることで無事終了する。そして、それをwaitで拾う

shell - Redirect stderr and stdout in Bash - Stack Overflow

本当は wait と jobs を組み合わせて格好よくやりたかったけど、どうも Process substitution で作ったプロセスは jobs で表示されない仕様らしい。