何が起こったか
jenkinsサーバを構築していてwhile文で躓いてしまったので備忘を兼ねて記事にします。
githubでjenkins job用のconfig.xmlを保存しておき、新しいファイルがpushされたらデプロイするようなjobを作成しておりました。既存jobのconfigに修正が入った場合もうまくデプロイできるように一度jobをjenkinsCLIコマンドにて全て削除し、新しいconfigファイルで全てgitからcloneしなおし、作成しなおすようなことをしています。
その削除コマンドがうまくいきませんでした。
実装は下記のようない感じです。
while read line
do
java -jar jenkins-cli.jar -s http://localhost:8080/ delete-job ${line}
done < delet_target_jobs.txt
job_a
job_b
job_c
jobが3つ全てある状態から上記を実行するとなぜかjob_aしかdeleteされません。
java -jar jenkins-cli.jar -s http://localhost:8080/ list-jobs
#job_b job_c
原因
調べてみるとどうやらwhile文で実行されるコマンドによってはファイル全体が標準入力になってしまい、whileループが1回で終了してしまうケースがあるらしいです。標準入力、標準出力についてはこちらで非常にわかりやすく解説されております。
javaコマンド以外だとsshコマンドもそれに該当するようで、下記もroop_me.txtが何行存在していても1回でroopが終了してしまいます。
while read line
do
ssh 192.168.0.1 touch $line
done < roop_me.txt
対策
sshコマンドの場合はオプション-n
を付けることで想定通り実行できます。
※-n は標準入力からの読み込みを禁止するオプションです。
while read line
do
ssh -n 192.168.0.1 touch $line
done < roop_me.txt
javaコマンドでは標準入力からの読み込みを禁止するオプションがないのでwhile文を使用しないことで対応できます。
for line in `cat delete_target_jobs.txt`
do
java -jar /var/lib/jenkins/jenkins-cli.jar -s http://localhost:8080/ delete-job ${line}
done
上記のようにすれば行数分確実にループが行われるので問題なく実行できました!
おわりに
ループが1回で終わってしまう現象が本当に分からず上記の内容にたどり着くまでとても時間を使ってしまいました。。。
linuxの標準入力/標準出力/標準エラー出力についてはもっと深い理解が必要だと感じたのでまた記事にしたいと思います。