サーバ管理者のためのプログラミング入門(シェルプログラミング基礎10~ループ処理その1) [サーバ管理者のプログラミング]
久々のエントリー。
条件分岐の次は「ループ処理」に進む。まず、シェルスクリプトを書く上で結構便利なループ方法から。
for 変数 in パラメータ1 ...
do
繰り返し処理
done
もうちょっと具体的にサンプルを示すとこんな感じ
内容としては、
・www.google.co.jp
・www.yahoo.co.jp
・www.goo.ne.jp
・www.excite.co.jp
の4つのサイトにpingを1回ずつ投げる…という程度のもの。
最初の「for」コマンドの行、「in」の後ろにはスペース(TABなどでもよい)で区切った文字列を並べると、それを1個目から順次変数(サンプルでは変数SITE)に代入して、「do」~「done」に囲まれた処理ブロックを1回ずつ実行するというもの。
上記のサンプルでは、
①変数SITEに「www.google.co.jp」を代入する
②ping -c www.google.co.jp を実行する
③変数SITEに「www.yahoo.co.jp」を代入する
④ping -c www.yahoo.co.jp を実行する
⑤変数SITEに「www.goo.ne.jp」を代入する
:
:
という感じになる。
例えば、複数のサーバに同じ処理をリモートで実行したい場合等に便利。
server1、server2、server3、server4、server5にそれぞれ「yum update」を実行したいという状況なら
とかすれば、いちいちログインして実行…とかしなくてもよい。(sshの鍵交換が済んでいないなら、いちいちパスワードは聞かれてしまうが。)
なお、for文のin句の後ろに並ぶ文字列は、左側から逐次処理されていくので、繰り返し処理が番号順でなく例えば「一番最初にserver5」を処理しなければならない場合等は「for SERVER in server5 server1 server2 server3 server4」とか記述することも可能。
それでは、上の「server1」~「server5」に連続してyum updateを実行するスクリプトを作成するとして、「サーバが生きていることを確認し、pingが通ったサーバにだけyum updateを実行したい…という処理を行ってみる。
いきなりサンプルを示すと、以下のようになる。
まず、「for SERVER in server1 server2...」の行。
これはこのアーティクルで説明しているとおり、繰り返し処理を行うことを意味している。変数SERVERに「server1」、「server2」…と順次代入されていく。その繰り返し行われる処理は、次の行「do」から「done」までの間の処理が対象となる。
「if ping -c 1 $SERVER > /dev/null 2>&1」は、変数SERVERに代入されている文字列(要するにサーバの名前)の示すサーバに対してpingを実行している。なお、pingはいろいろ表示されてうっとうしいので、/dev/nullにpingの実行結果を捨てている。
このpingが正常終了すると、次の行「then」から「fi」までの間の処理が行われ、pingが異常終了した場合(pingが通らないとか、サーバ名が解決できない場合)は、else句が無いので特に何も実行しない。
このように、forやifの処理はブロックの中にそれぞれ入れ子にすることも可能である。
条件分岐の次は「ループ処理」に進む。まず、シェルスクリプトを書く上で結構便利なループ方法から。
for 変数 in パラメータ1 ...
do
繰り返し処理
done
もうちょっと具体的にサンプルを示すとこんな感じ
#!/bin/sh for SITE in www.google.co.jp www.yahoo.co.jp www.goo.ne.jp www.excite.co.jp do ping -c 1 $SITE done
内容としては、
・www.google.co.jp
・www.yahoo.co.jp
・www.goo.ne.jp
・www.excite.co.jp
の4つのサイトにpingを1回ずつ投げる…という程度のもの。
最初の「for」コマンドの行、「in」の後ろにはスペース(TABなどでもよい)で区切った文字列を並べると、それを1個目から順次変数(サンプルでは変数SITE)に代入して、「do」~「done」に囲まれた処理ブロックを1回ずつ実行するというもの。
上記のサンプルでは、
①変数SITEに「www.google.co.jp」を代入する
②ping -c www.google.co.jp を実行する
③変数SITEに「www.yahoo.co.jp」を代入する
④ping -c www.yahoo.co.jp を実行する
⑤変数SITEに「www.goo.ne.jp」を代入する
:
:
という感じになる。
例えば、複数のサーバに同じ処理をリモートで実行したい場合等に便利。
server1、server2、server3、server4、server5にそれぞれ「yum update」を実行したいという状況なら
#!/bin/sh for SERVER in server1 server2 server3 server4 server5 do ssh $SERVER yum -y update done
とかすれば、いちいちログインして実行…とかしなくてもよい。(sshの鍵交換が済んでいないなら、いちいちパスワードは聞かれてしまうが。)
なお、for文のin句の後ろに並ぶ文字列は、左側から逐次処理されていくので、繰り返し処理が番号順でなく例えば「一番最初にserver5」を処理しなければならない場合等は「for SERVER in server5 server1 server2 server3 server4」とか記述することも可能。
それでは、上の「server1」~「server5」に連続してyum updateを実行するスクリプトを作成するとして、「サーバが生きていることを確認し、pingが通ったサーバにだけyum updateを実行したい…という処理を行ってみる。
いきなりサンプルを示すと、以下のようになる。
#!/bin/sh for SERVER in server1 server2 server3 server4 server5 do if ping -c 1 $SERVER > /dev/null 2>&1 then #pingが通った場合の処理 ssh $SERVER yum -y update fi done
まず、「for SERVER in server1 server2...」の行。
これはこのアーティクルで説明しているとおり、繰り返し処理を行うことを意味している。変数SERVERに「server1」、「server2」…と順次代入されていく。その繰り返し行われる処理は、次の行「do」から「done」までの間の処理が対象となる。
「if ping -c 1 $SERVER > /dev/null 2>&1」は、変数SERVERに代入されている文字列(要するにサーバの名前)の示すサーバに対してpingを実行している。なお、pingはいろいろ表示されてうっとうしいので、/dev/nullにpingの実行結果を捨てている。
このpingが正常終了すると、次の行「then」から「fi」までの間の処理が行われ、pingが異常終了した場合(pingが通らないとか、サーバ名が解決できない場合)は、else句が無いので特に何も実行しない。
このように、forやifの処理はブロックの中にそれぞれ入れ子にすることも可能である。
コメント 0