サーバ管理者のためのプログラミング入門(シェルプログラミング基礎7~条件分岐その3) [サーバ管理者のプログラミング]
数値の大小比較を行うコマンド「test」は、他にも文字列の比較も可能である。比較できる内容としては、ごく一般的な
1.2個の文字列が等しいかどうか/等しくないかどうか
2.与えられた文字列が「空」かどうか/「空ではない」かどうか
というもの。
1.2個の文字列が等しいかどうか/等しくないかどうか
文字列の比較も、数値の比較と同様に基本的な機能だと思うが、その方法を説明する。
例を見てほしい。
まるで面白みもないサンプルで申し訳ないが、これで要所は説明できるので説明したい。(笑)
まず、重要なのは次の2点。
ポイント1 文字列の比較には「=」記号を用いる
ポイント2 比較する2個の文字列は必ずダブルクォートで囲むこと
文字列が一致するかどうかの判定には、「=」記号を用いる。これは判りやすいと思う。ただ、うっかり数値の比較で用いたりしないことに注意しよう。なぜか?以下の例を見てもらいたい。(スクリプトを書くのが面倒くさかったのでコマンドを手入力している。:笑)
変数Aには「2」が代入されている。一方、変数Bには「+2」が代入されている。両方とも、数学的には同じ数値である。だから、testコマンドで-eqオプションを指定して比較している結果は0なので「真」…つまり両者は等しいと判定されている。一方、=オプションを指定して比較している結果は1なので「偽」…つまり両者は等しくないと判定されている。
このような結果の違いを招くので、-eqと=とは正しく使い分けなければならない。
次に、比較する2個の文字列は必ずダブルクォートで囲む必要が有る。いや、正確には囲むべきであるというべきかもしれない。その理由を説明しよう。
実は、上記のサンプルではあえて囲まないで文字列の比較を実行しているが、エラーになっていないことが判るだろうか。これは、変数Aにも変数Bにも何らかの文字列が入っているから問題なく実行できているのである。
では、以下の例を見てほしい。
変数Aには「ABC」という文字列が入っているが、変数Bには何も入っていない(正確にはヌル・ストリングを代入している)
すると、testコマンドは変数が展開された状態では
test ABC =
という状態でコマンドが実行された状態になってしまい、イコール記号の後ろにパラメータが不足している状態になってしまっている。このためエラーになってしまった。これを回避するために、ダブルクォートで囲む必要が有るのである。
このようにすると、変数Aと変数Bとの比較が実行され、等しくないという結果を得ることができている。変数が展開された状態を見ると一目瞭然。
test "ABC" = ""
と、イコール記号の後ろに何らかのパラメータがあることがtestコマンドにちゃんと伝わるのである。
文字列比較を行う場合には、100%必須というわけではないが、変数の中身がカラッポだった場合に備えてダブルクォートで囲んでおく癖をつけるべきである。
なお、2個の文字列が一致しない場合に真と判定したい場合は、「=」記号の代わりに「!=」を用いる。
変数Aと変数Bとはそれぞれ異なる文字列が入っている。そして、その比較をしたtestコマンドの結果が0…つまり真になっている。
2.与えられた文字列が「空」かどうか/「空ではない」かどうか
シェルスクリプトの中ではこちらもわりとよく用いられる条件判断になる。変数がカラッポなのか、カラッポでないか?というものである。
まずは、変数がカラッポではない場合の条件判断を見てみよう。
if構文・testコマンドの引数に注目。なんと、単にダブルクォートで囲んだ変数が記述されているだけになっている。これをシェルスクリプトとして実行するとこんな具合になる。
まずはシェルスクリプトをそのまま引数無しで実行すると…
「パラメータはありません。」と表示された。つまり、testコマンドの実行結果は0でなかった(=つまり「偽」だった)ことを示している。
では、何らかのパラメータをつけて実行してみるとどうか。
一方、変数の中身がカラッポだったら…という判断を行いたいケースでは、test -z "変数" という具合に、「-z」オプションを用いることになる。
1.2個の文字列が等しいかどうか/等しくないかどうか
2.与えられた文字列が「空」かどうか/「空ではない」かどうか
というもの。
1.2個の文字列が等しいかどうか/等しくないかどうか
文字列の比較も、数値の比較と同様に基本的な機能だと思うが、その方法を説明する。
例を見てほしい。
#!/bin/sh MOJI_A="ABCDEFG" MOJI_B="ABCDEFG" if test "$MOJI_A" = "$MOJI_B" then # 2個の文字列は一致した echo "一致しました" else # 2個の文字列は一致しなかった echo "一致しませんでした" fi
まるで面白みもないサンプルで申し訳ないが、これで要所は説明できるので説明したい。(笑)
まず、重要なのは次の2点。
ポイント1 文字列の比較には「=」記号を用いる
ポイント2 比較する2個の文字列は必ずダブルクォートで囲むこと
文字列が一致するかどうかの判定には、「=」記号を用いる。これは判りやすいと思う。ただ、うっかり数値の比較で用いたりしないことに注意しよう。なぜか?以下の例を見てもらいたい。(スクリプトを書くのが面倒くさかったのでコマンドを手入力している。:笑)
[root@server ~]# A="2" [root@server ~]# B="+2" [root@server ~]# test $A -eq $B [root@server ~]# echo $? 0 [root@server ~]# test $A = $B [root@server ~]# echo $? 1
変数Aには「2」が代入されている。一方、変数Bには「+2」が代入されている。両方とも、数学的には同じ数値である。だから、testコマンドで-eqオプションを指定して比較している結果は0なので「真」…つまり両者は等しいと判定されている。一方、=オプションを指定して比較している結果は1なので「偽」…つまり両者は等しくないと判定されている。
このような結果の違いを招くので、-eqと=とは正しく使い分けなければならない。
次に、比較する2個の文字列は必ずダブルクォートで囲む必要が有る。いや、正確には囲むべきであるというべきかもしれない。その理由を説明しよう。
実は、上記のサンプルではあえて囲まないで文字列の比較を実行しているが、エラーになっていないことが判るだろうか。これは、変数Aにも変数Bにも何らかの文字列が入っているから問題なく実行できているのである。
では、以下の例を見てほしい。
[root@server ~]# A="ABC" [root@server ~]# B="" [root@server ~]# test $A = $B -bash: test: ABC: unary operator expected
変数Aには「ABC」という文字列が入っているが、変数Bには何も入っていない(正確にはヌル・ストリングを代入している)
すると、testコマンドは変数が展開された状態では
test ABC =
という状態でコマンドが実行された状態になってしまい、イコール記号の後ろにパラメータが不足している状態になってしまっている。このためエラーになってしまった。これを回避するために、ダブルクォートで囲む必要が有るのである。
[root@server ~]# A="ABC" [root@server ~]# B="" [root@server ~]# test "$A" = "$B" [root@server ~]# echo $? 1
このようにすると、変数Aと変数Bとの比較が実行され、等しくないという結果を得ることができている。変数が展開された状態を見ると一目瞭然。
test "ABC" = ""
と、イコール記号の後ろに何らかのパラメータがあることがtestコマンドにちゃんと伝わるのである。
文字列比較を行う場合には、100%必須というわけではないが、変数の中身がカラッポだった場合に備えてダブルクォートで囲んでおく癖をつけるべきである。
なお、2個の文字列が一致しない場合に真と判定したい場合は、「=」記号の代わりに「!=」を用いる。
[root@server ~]# A="UNIX" [root@server ~]# B="Linux" [root@server ~]# test "$A" != "$B" [root@server ~]# echo $? 0
変数Aと変数Bとはそれぞれ異なる文字列が入っている。そして、その比較をしたtestコマンドの結果が0…つまり真になっている。
2.与えられた文字列が「空」かどうか/「空ではない」かどうか
シェルスクリプトの中ではこちらもわりとよく用いられる条件判断になる。変数がカラッポなのか、カラッポでないか?というものである。
まずは、変数がカラッポではない場合の条件判断を見てみよう。
#!/bin/sh if test "$1" then echo "パラメータは"$1"です。" else echo "パラメータはありません。" fi
if構文・testコマンドの引数に注目。なんと、単にダブルクォートで囲んだ変数が記述されているだけになっている。これをシェルスクリプトとして実行するとこんな具合になる。
まずはシェルスクリプトをそのまま引数無しで実行すると…
[root@kagami tmp]# ./string.sh パラメータはありません。
「パラメータはありません。」と表示された。つまり、testコマンドの実行結果は0でなかった(=つまり「偽」だった)ことを示している。
では、何らかのパラメータをつけて実行してみるとどうか。
[root@kagami tmp]# ./string.sh ABC パラメータはABCです。
一方、変数の中身がカラッポだったら…という判断を行いたいケースでは、test -z "変数" という具合に、「-z」オプションを用いることになる。
コメント 0