while-read loop

障害

次のコードは find の処理でよく使われる典型的な手法です*1

find . -type f -path "*.ts" | {
    while read f
    do
	echo "$f"
    done }


うまく行きますし、保守しやすいコードなので、多用しています。ところが、次のコードはうまく行くように見えますが、flag の値はnullです。

# 障害
echo "test message: ok" | {
    while read mssg
    do
	if [[ "$mssg" =~ ok ]]; then
	    flag=1
	    break
	fi
    done }
echo "flag: $flag"

対策

Bash: Piped `while-read' loop starts subshellにありました。

# 対策
flag=$(echo "test message: ok" | {
	while read mssg
	do
	    if [[ "$mssg" =~ ok ]]; then
		echo 1
		break
	    fi
	done }
    )
echo "flag: $flag"


原因は while-read loop がサブシェルになるからだそうです。

*1:while-readを"{}"で囲む必要はありません。範囲をわかり易くしてるだけです