kshでwhile readを使って1行ずつ処理するプログラムを書いていて,その中でrshコマンドを実行するとその時点でループが止まってしまうという謎の事象に遭遇した.はじめはどこか別のところにバグがあるんだろうと思ってコードを削ってみたり,テストコードを書いてみたり,デバッグしてみたりしたが,最終的にはwhile readの骨組みしか残らなくなって(笑),rshを外すとちゃんとループが回ることともわかったので,何やらrshが悪さしてるんじゃないかみたいなところまで特定することができた.
そこで"sh while read rsh"でググってみたところ,同じ事象がじゃんじゃん出てくるわで,なんだ同じところで悩んでる人たくさんいるじゃないかってちょっと安心した.ということで,せっかくなのでまとめておく.ちなみに今回の動作言語はkshだけど,bashでもその他の類似シェルスクリプトでもきっと一緒なはず.あと今回のコマンドはrshだけど,sshでも同じらしい.
関連エントリー
shのwhileループでファイルを読み、中でsshを実行すると1回しかループしない - b.l0g.jp
sshを使うとbashのループが回らない?
Shell にて rsh を while で実行する際の不具合 − Linux Square − @IT
question about rsh and read - UNIX Scripting - Tek-Tips
簡単な動作解説
まず動作以下のようなconfファイルを用意して,その中に実行するコマンドを書いておく.
./cmd_list.conf(ダメな例)
CMD1 rsh node1 CMD2 CMD3
このconfファイルをwhile readで1行ずつ回しながら実行していくシェルが以下.${CMD}で実行されるのが期待値だけど,2行目のrshを実行したところでループが終了してしまう.
./cmd_exec.ksh
#!/bin/ksh while read CMD; do # リストに定義したコマンドを実行する ${CMD} done < ./cmd_list.conf
実行対象(コマンド実行)
CMD1
rsh node1 CMD2
そこでコマンドを実行せずに標準出力してみると,正常に動作するので,何やらrshが悪さしてるんじゃないかみたいな.
./cmd_exec.ksh
#!/bin/ksh while read CMD; do # リストに定義したコマンドを標準出力する print ${CMD} done < ./cmd_list.conf
実行対象(標準出力のみ)
CMD1
rsh node1 CMD2
CMD3
原因はrshで,rshに-nオプションを付けて標準入力をリダイレクトしないようにしてあげることで,問題は解決する.以下のようにconfファイルを修正して完了.お疲れ様でした.
./cmd_list.conf(正しい例)
CMD1 rsh node1 -n CMD2 CMD3