--/--/-- (--)
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
2010/12/19 (日)
シェルスクリプトというものは、分解すれば結局はそのほとんどがコマンドでできている。

例えば以下の例、

if [ $num = 0 ] ; then
echo "hoge"
fi

まぁ、典型的なif文の使用例である。

「もしも変数numの値が0だったらhogeを表示」みたいな。

これを厳密に書くと以下のようになる。

if test $num -eq 0
then
echo "hoge"
fi

if文の"if"の後ろには"条件式"を記述しているのではなく、
"コマンド"を記述していると意識したほうが良い。
コマンドの終了コードによって分岐するしないを判断している。

"[]"というのはあくまでtestコマンドの省略系である。
"$num = 0"とはtestコマンドの引数で$numと0の文字列比較を表している。

さらに、厳密に言えば"[ $num = 0 ]"というのも"["コマンドである。
試しに"which ["とかやってみると、/usr/binあたりに[コマンドが見つかる。
"]"という引数が[コマンドの引数の終わりを示している。
よく"["と"$num"の間には必ずスペースが必要なのは変な制約だとか言う人がいるけど、
それはコマンドとコマンドの引数の間にスペースが必要という、ごく当たり前の制約である。

"="と"-eq"の違いは文字列比較と数値比較の違いである。
どっちもtestコマンドオプションである。
例のように意図した条件分岐ができたとしても"="で数値比較するのはおかしい。
これらはman testとかやると詳細を知ることができる。
よく[ -f ~/hoge.txt ]"とか"[ -d ~/hoge ]"とか"ファイルの存在を調べるにはどうするんだっけとか聞かれるけど、
man testして調べれば一瞬で解決する話。

先ほど言ったように、if の後ろはコマンドの終了コードによって分岐するしないを判断する。
つまりifの後ろは必ずしも"[ ]"や、まして"test"でなくても良いとわかる。

if grep "hoge" hoge.txt

なんて記述も、わかってしまえば普通である。
grepコマンドは、該当の文字列が存在しなければエラーの終了コードを吐くので条件判断に使えるのだ。
ただし、grepは検索結果を標準出力に出すので、

if grep "hoge" hoge.txt > /dev/null

とするのが賢い。
また、先ほどの、ファイルの存在を調べるオプションは-fだったっけみたいなのも、もはや
if ls hoge.txt > dev/null
で解決するかもしれない。

"; then"というのは;はコマンドの改行、その後thenを入力しているに過ぎないのは、もうわかるだろう。



こうして考えると、

if [ $num = 1 ] && [ $num = 2 ]; then

の本当の意味もわかってくるだろう
&&というのは前のコマンドの終了コードがエラーでなければ次のコマンドを実行するという、選択実行である。
つまり"num = 1"がエラーの終了コードを吐けば$num = 2は評価されない。
ちなみに||は前のコマンドがエラーの終了コードを吐くと次のコマンドを実行するという選択実行、
;は前のコマンドの終了コードによらない連続実行である。

if [ $num = 1 -a $num = 2 ]; then

も分岐結果は同じになるが、(-aはandに相当するオプション)
後ろの式も評価される。

このへんを理解していると、シェルスクリプトの動作が格段にわかるようになる。

昔はzshの機能に頼って

for i in {0..5}

なんて記述をしていたけど、最近はなんとなく

for i in `seq 0 5`

という記述をするようになってしまった。
このほうが、厳密で好き。

どう展開されるかなんて、やってみないとわからないから
コメント
この記事へのコメント
コメントを投稿する
URL:
Comment:
Pass:
秘密: 管理者にだけ表示を許可する
 
トラックバック
この記事へのトラックバック
この記事のトラックバックURL
http://tochiii.blog119.fc2.com/tb.php/253-b109d8a6
この記事にトラックバックする(FC2ブログユーザー)
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。