サーバ管理者のためのプログラミング入門(シェルプログラミング基礎5~条件分岐) [サーバ管理者のプログラミング]
最初に登場するのは、「条件分岐」。これがなくては何も始まらない。
およそプログラミング言語たるもの、「もし、○○が××だったら、……をする。そうでなかったら~~をする。」という仕組みは必ず持っているものである。そして、シェルスクリプトだって例外なくそういう仕組みを持っているのである。ただし、世間一般のプログラミング言語がもっている条件判断の構文とちょっと違うので、そこだけ要注意。
まずは書式から。
if (コマンドA)
then
(コマンドB)
fi
最小の基本形としてはこんな感じ。
まず、「コマンドA」が実行される。そのコマンドの実行結果(終了ステータス)が0(≒正常終了)だった場合に、「コマンドB」が実行されるのである。
pingを使って実例を示そう。pingを投げてみて正常だったら、「ping OK」と表示させる簡単なもの。
これを実行すると…
pingコマンドの結果も混じってしまって見づらいが、最後に「ping OK」と表示が出ていることがわかる。
「localhost」だった箇所を「null.void」とかにするとどうなるか。
これを実行すると、
「ping OK」とは表示されなくなったことがわかる。
では、pingが失敗したときに、「ping NG」と表示したい場合はどうしようか。つまり、「もし、コマンドが失敗したら…」という条件判断をしたい場合。
そのような時には、ifとコマンドAとの間に「!」を置くとよい。つまり、
if ! (コマンドA)
then
(コマンドB)
fi
という形にする。すると、コマンドAの終了ステータスが0でなかった場合にコマンドBが実行されるようになる。
先ほどのスクリプトを修正する。なお、いちいち面倒くさいのでpingのに渡す引数はシェルスクリプトの「位置パラメータ」を渡すようにした。(笑)
これで実行する場合は、「ping_script.sh localhost」みたいに実行するのである。
やってみる。
このように、今度は「localhost」に対するpingではコマンドBに相当するechoが実行されていないが、「null.void」に対するpingではコマンドBに相当する部分が実行されていることがわかる。
では、ping OKと、ping NGとを一緒に判断したい場合を紹介する。
if (コマンドA)
then
(コマンドB)
else
(コマンドC)
fi
このように、「then」と「fi」との間に、「else」とコマンドCを追加する。すると、
・コマンドAの終了ステータスが0だった場合 … コマンドBが実行される
・コマンドAの終了ステータスが0でなかった場合 … コマンドCが実行される
という挙動になる。pingの例で実例を示す。
このようなシェルスクリプトに修正する。pingが成功したときと失敗したときとでping OK、ping NGの表示が変わることを確認しよう。
と、このようにOK、NGの表示が変化している事が確認できる。
このように、コマンドAの実行結果に応じて、処理を分岐することができるのである。
と、ここで平和裏に終わらせたいところではあるが、なにか釈然としない気持ちを持った人もいるだろう。(笑)そんな人には次のアーティクルを期待していただきたい。(笑)
およそプログラミング言語たるもの、「もし、○○が××だったら、……をする。そうでなかったら~~をする。」という仕組みは必ず持っているものである。そして、シェルスクリプトだって例外なくそういう仕組みを持っているのである。ただし、世間一般のプログラミング言語がもっている条件判断の構文とちょっと違うので、そこだけ要注意。
まずは書式から。
if (コマンドA)
then
(コマンドB)
fi
最小の基本形としてはこんな感じ。
まず、「コマンドA」が実行される。そのコマンドの実行結果(終了ステータス)が0(≒正常終了)だった場合に、「コマンドB」が実行されるのである。
pingを使って実例を示そう。pingを投げてみて正常だったら、「ping OK」と表示させる簡単なもの。
#!/bin/sh if ping -c 1 localhost then echo "ping OK" fi
これを実行すると…
[root@kagami tmp]# ./ping_script.sh PING kagami (127.0.0.1) 56(84) bytes of data. 64 bytes from kagami (127.0.0.1): icmp_seq=1 ttl=64 time=0.148 ms --- kagami ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.148/0.148/0.148/0.000 ms ping OK
pingコマンドの結果も混じってしまって見づらいが、最後に「ping OK」と表示が出ていることがわかる。
「localhost」だった箇所を「null.void」とかにするとどうなるか。
#!/bin/sh if ping -c 1 null.void then echo "ping OK" fi
これを実行すると、
[root@kagami tmp]# ./ping_script.sh ping: unknown host null.void
「ping OK」とは表示されなくなったことがわかる。
では、pingが失敗したときに、「ping NG」と表示したい場合はどうしようか。つまり、「もし、コマンドが失敗したら…」という条件判断をしたい場合。
そのような時には、ifとコマンドAとの間に「!」を置くとよい。つまり、
if ! (コマンドA)
then
(コマンドB)
fi
という形にする。すると、コマンドAの終了ステータスが0でなかった場合にコマンドBが実行されるようになる。
先ほどのスクリプトを修正する。なお、いちいち面倒くさいのでpingのに渡す引数はシェルスクリプトの「位置パラメータ」を渡すようにした。(笑)
[root@kagami tmp]# cat ping_script.sh #!/bin/sh if ! ping -c 1 $1 then echo "ping NG" fi
これで実行する場合は、「ping_script.sh localhost」みたいに実行するのである。
やってみる。
[root@kagami tmp]# ./ping_script.sh localhost PING kagami (127.0.0.1) 56(84) bytes of data. 64 bytes from kagami (127.0.0.1): icmp_seq=1 ttl=64 time=0.527 ms --- kagami ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.527/0.527/0.527/0.000 ms [root@kagami tmp]# ./ping_script.sh null.void ping: unknown host null.void ping NG
このように、今度は「localhost」に対するpingではコマンドBに相当するechoが実行されていないが、「null.void」に対するpingではコマンドBに相当する部分が実行されていることがわかる。
では、ping OKと、ping NGとを一緒に判断したい場合を紹介する。
if (コマンドA)
then
(コマンドB)
else
(コマンドC)
fi
このように、「then」と「fi」との間に、「else」とコマンドCを追加する。すると、
・コマンドAの終了ステータスが0だった場合 … コマンドBが実行される
・コマンドAの終了ステータスが0でなかった場合 … コマンドCが実行される
という挙動になる。pingの例で実例を示す。
#!/bin/sh if ping -c 1 $1 then echo "ping OK" else echo "ping NG" fi
このようなシェルスクリプトに修正する。pingが成功したときと失敗したときとでping OK、ping NGの表示が変わることを確認しよう。
[root@kagami tmp]# ./ping_script.sh localhost PING kagami (127.0.0.1) 56(84) bytes of data. 64 bytes from kagami (127.0.0.1): icmp_seq=1 ttl=64 time=0.484 ms --- kagami ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.484/0.484/0.484/0.000 ms ping OK [root@kagami tmp]# ./ping_script.sh null.void ping: unknown host null.void ping NG
と、このようにOK、NGの表示が変化している事が確認できる。
このように、コマンドAの実行結果に応じて、処理を分岐することができるのである。
と、ここで平和裏に終わらせたいところではあるが、なにか釈然としない気持ちを持った人もいるだろう。(笑)そんな人には次のアーティクルを期待していただきたい。(笑)
コメント 0