LoginSignup
0
0

More than 3 years have passed since last update.

shellscriptのwhile文が1回目のループで終了してしまう。。。

Last updated at Posted at 2020-01-06

何が起こったか

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
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の標準入力/標準出力/標準エラー出力についてはもっと深い理解が必要だと感じたのでまた記事にしたいと思います。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0