今回はシェルについて(bash)
とりあえずなんとなくシェルを書いていてつまづいたことがあった。
そう、readコマンドについて、である。
今回はまったケースは
・while readのループの中で新しくreadコマンドでキーボード入力をしたかったけど
実際にはwhile readで読み込んだ行の次の行が読み込まれてしまう
という現象。
まずは事象について
test.sh
#!/bin/bash file_name=name.lst cat ${file_name} | while read line; do echo "Well..." echo "Are you ${line}? [y/n]" read answer if [[ ${answer} = y ]]; then echo "Yes, you are completely ${line}." echo "Have a good time." exit 1 fi echo "Oh, so sorry..." done if [[ $? -eq 1 ]]; then exit 1 fi echo "I don't know you." exit 0
name.lst
footaro bartaro hogeko
これの実行結果は例えば次のようになる。
Well... Are you footaro? [y/n] Oh, so sorry... Well... Are you hogeko? [y/n] Oh, so sorry... I don't know you.
キーボード入力したかったのに勝手に進んで終了してしまった。私hogekoなのに。。。
っていう悲しい結果になる(bartaroは!?)
ぐぐったところ、キーボードからの入力にしたい場合には
read answer
を
read answer < /dev/tty
とすればよいらしい。
実行結果
Well... Are you footaro? [y/n] n Oh, so sorry... Well... Are you bartaro? [y/n] n Oh, so sorry... Well... Are you hogeko? [y/n] y Yes, you are completely hogeko. Have a good time.
よしよし。hogekoって言えたぞ。
Tips
ちなみにwhileループの中でexitを用いてもループを抜けるだけでシェル自体は終了できないので
ループを抜けた後に判定する必要もあるらしい(ぐぐった)
今回ぐぐったサイト
シェルスクリプトでパイプからの入力とキーボード入力を区別する - rcmdnk’s blog
bashはwhile内の処理が子プロセス扱いになる - Alligator Swamp