2009年2月27日金曜日

ずっと/bin/shの「$@」の使い方を間違えていた

なんかみっともない話ですが、使い方を間違えてたんです・・・。



$@は、コマンドラインで指定した引数が入ってくるんですが、引数にスペースを含んだ文字列を指定した場合の振る舞いが特徴的です。
こんなシェルスクリプトで動作確認ができます。

#! /bin/sh
i=0
for a in "$@"
do
    echo $i : $a
    i=`expr $i + 1`
done

ためしに実行してみると

% sh ./arg.sh abc "def ghi"
0 : abc
1 : def ghi

という動きをします。



これを、私はずっと間違えていて、こう書いてたんです。

(一部のみ抜粋)
for a in $@
do
    echo $i : $a
    i=`expr $i + 1`
done

ただ、「"$@"」と「$@」の違いだけなんですが、動きは大違い。

% sh ./arg.sh abc "def ghi"
0 : abc
1 : def
2 : ghi

スペースが入ってると、そこで分離されてしまうんですね。
というわけで「"$@"」と書かなければならない!ということ。





$@によく似た変数で、$*があります。



"$*"」で使うと・・・

(一部のみ抜粋)
for a in "$*"
do
    echo $i : $a
    i=`expr $i + 1`
done

実行してみます。

% sh ./arg.sh abc "def ghi"
0 : abc def ghi

$*」で使うと・・・

(一部のみ抜粋)
for a in $*
do
    echo $i : $a
    i=`expr $i + 1`
done

実行してみると

% sh ./arg.sh abc "def ghi"
0 : abc
1 : def
2 : ghi

なんか微妙・・・これはまる暗記して覚えるしかないのかも。




こういう書き方

i=`expr $i + 1`

を最初に覚えたので、ずっとこの書き方を使ってるんですが、今どきの/bin/shでは

i=$((i+1))

という書き方もできるそうです。

i=$(($i+1))

と書いても同じ結果になるんですが、ふ~ん。



exprを使わなくてすむ分、性能向上しそうなので、じゃあ、これからこっちにしよう!と思ったら、Solarisの/bin/shではこの書き方、使えませんでした。ぎゃふん。



0 件のコメント:

コメントを投稿