成功したら何も出さないけど、失敗したらエラー内容を出力して終わりたい、ということがある。
test1.sh:
#!/bin/bash
compute() {
$((3 / 0))
}
echo -n 'computing ... '
out=$(compute 2>&1)
ret=$?
if [ $ret -eq 0 ] ; then
echo '[OK]'
else
echo '[NG]'
echo "$out"
fi
exit $ret
これは意図通りに動く。
$ bash test1.sh
computing ... [NG]
test1.sh: line 4: 3 / 0: division by 0 (error token is "0")
しかし Bash を使っていて local を使わないなんて あり得ない ので、
test2.sh:
#!/bin/bash
compute() {
$((3 / 0))
}
main() {
echo -n 'computing ... '
local out=$(compute 2>&1)
local ret=$?
if [ $ret -eq 0 ] ; then
echo '[OK]'
else
echo '[NG]'
echo "$out"
fi
return $ret
}
main
$ bash test2.sh
computing ... [OK]
はい、動かなくなったー。何で!?
長い間この理由が分からなくて、挙句 Bash のバグじゃねーの?と疑ったこともあったが、ずっと後になって謎が解けた。
local が実行結果を返すなんて知らなかったよ・・・。 orz
local は関数内で使われる限り失敗しないので、「local out=$(...)」の結果は常に真になる。なので正しくはこう。
test3.sh:
#!/bin/bash
compute() {
$((3 / 0))
}
main() {
echo -n 'computing ... '
local out
out=$(compute 2>&1)
local ret=$?
if [ $ret -eq 0 ] ; then
echo '[OK]'
else
echo '[NG]'
echo "$out"
fi
return $ret
}
main
$ bash test3.sh
computing ... [NG]
test3.sh: line 4: 3 / 0: division by 0 (error token is "0")
もう Bash さん、疑ったりして本当にすみません。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。