PR
 シェル・スクリプト・リファンレス
コマンド集(機能別) | コマンド集(アルファベット順) | コマンド逆引き大全 | シェル・スクリプト・リファンレス

 位置パラメータ

 コマンドやシェル・スクリプトを実行する場合に,コマンド名などの後に文字などを指定して,コマンドにその値を渡すことができる。この値のことを引数と呼ぶ。たとえば,cpコマンドでは,


$ cp src_file dist_file 

のようにして,src_fileとdist_fileの2つの値を引数として渡している。

 シェル・スクリプト内ではこの引数を,「位置パラメータ」と呼ぶ特殊な変数に代入している。位置パラメータは「$0」から「$9」の10個用意されている。「$0」には実行したコマンドやシェル・スクリプトそのものが代入され,$1から$9には引数が指定された順に代入される。

 たとえば,以下のようなシェル・スクリプト「arg.sh」があったとする。


#!/bin/sh

echo "0:$0 1:$1 2:$2 3:$3 4:$4 5:$5 6:$6 7:$7 8:$8 9:$9"

 このシェル・スクリプトにいくつかの引数を与えると,


$ ./arg.sh arg1 file dir 15 31 
0:./arg.sh 1:arg1 2:file 3:dir 4:15 5:31 6: 7: 8: 9:

のように各位置パラメータに代入される。$6から$9までは対象となる引数がないため,NULL状態になる。


 引数の数

 「$#」には実行したコマンドやシェル・スクリプトなどの引数の数が代入される。たとえば,以下のようなシェル・スクリプト「count.sh」があったとする。


#!/bin/sh

echo "arg number:$#"

 この,シェル・スクリプトにいくつかの引数を与えると,


$ ./count.sh arg1 arg2 arg3 
arg number:4

のように引数の数が表示される。ただし,実行コマンド自身も1つと数えられる。


 位置パラメータをずらす

 位置パラメータは$0から$9の10個しか利用できない。もし,それ以上の引数(コマンド自身も含む)を利用したい場合は,shiftで位置パラメータをずらして利用する。shiftを実行すると,引数は$1に$2の値,$2に$3の値・・・$8に$9の値と1個ずつずれていく。また,$9には引数の10個目が新しく入れられる。ただし,$0は対象にはならない。

 たとえば,以下のようなシェル・スクリプト「shift.sh」があったとする。


#!/bin/sh

echo "before shift : 0:$0 1:$1 2:$2 3:$3 4:$4 5:$5 6:$6 7:$7 8:$8 9:$9"
shift
echo "after shift  : 0:$0 1:$1 2:$2 3:$3 4:$4 5:$5 6:$6 7:$7 8:$8 9:$9"

 このシェル・スクリプトに引数を10個与えると,


$ ./shift.sh a b c d e f g h i j 
before shift : 0:./shift.sh 1:a 2:b 3:c 4:d 5:e 6:f 7:g 8:h 9:i
after shift  : 0:./shift.sh 1:b 2:c 3:d 4:e 5:f 6:g 7:h 8:i 9:j

と,位置パラメータが1つずつずれている。また,$9には10個目の引数が代入されている。

 shiftの後に数字を指定すると,その指定した数字分,位置パラメータがずれていく。たとえば,上記したシェル・スクリプトでshiftを「shift 5」とすると,


$ ./shift.sh a b c d e f g h i j k l m n
before shift : 0:./shift.sh 1:a 2:b 3:c 4:d 5:e 6:f 7:g 8:h 9:i
after shift  : 0:./shift.sh 1:f 2:g 3:h 4:i 5:j 6:k 7:l 8:m 9:n

のようになる。


 位置パラメータの再設定

 位置パラメータは読み込み専用であるため,ユーザーが勝手に書き換えることはできない。たとえば,シェル・スクリプト上で


$1=new_arg

などとすると,エラーが発生して値を変更することはできない。

 位置パラメータを変更したい場合はsetを利用する。たとえば,以下のようなシェル・スクリプト「change_set.sh」があったとする。


#!/bin/sh

echo "before set : 0:$0 1:$1 2:$2"
set new_arg1 new_arg2
echo "after set  : 0:$0 1:$1 2:$2"

 このシェル・スクリプトに引数を与えて実行すると,


$ ./change_set.sh org_arg1 org_arg2
before set : 0:./change_set.sh 1:org_arg1 2:org_arg2
after set  : 0:./change_set.sh 1:new_arg1 2:new_arg2

のように,引数が変更される。ただし,実行コマンド自身を表す$0は変更されない。


 引数をひとまとめにする

 受け取った引数をシェル・スクリプト上で他のコマンドなどにそのまま引き渡したい場合は,「$*」や「$@」,「"$*"」,「"$@"」を利用する。それぞれには,表のような意味がある。


記号 意味
$* 全ての引数をスペースで区切りながらつなげて,そのまま引き渡す
$@ $*と同じ
"$*" 全ての引数を1つの引数として扱って引き渡す
"$@" "..."などでくくられた引数を1つの引数として扱って引き渡す

 たとえば,以下のようなシェル・スクリプト「echo_arg.sh」,


#!/bin/sh

echo "1:$1 2:$2 3:$3"

と,以下のようなシェル・スクリプト「pass_arg.sh」,


#!/bin/sh

echo -n '$*   : '
./echo_arg.sh $*

echo -n '$@   : '
./echo_arg.sh $@

echo -n '"$*" : '
./echo_arg.sh "$*"

echo -n '"$@" : '
./echo_arg.sh "$@"

があったとする。pass_arg.shに「a b」と「c」の2つの引数を与えて実行すると,


$ ./pass_arg.sh "a b" c 
$*   : 1:a 2:b 3:c
$@   : 1:a 2:b 3:c
"$*" : 1:a b c 2: 3:
"$@" : 1:a b 2:c 3:

のようになる。

 「$*」と「$@」は引数をつなげてから引き渡すため,「echo_arg.sh a b c」と実行したのと同じになる。よって引数は「a」,「b」,「c」の3つに別れてしまう。

 「"$*"」は全ての引数を1つとして扱って引き渡すため,「echo_arg.sh "a b c"」と実行したのと同じになる。よって引数は「a b c」の1つになる。

 「"$@"」は"..."や'...'でくくられた引数を1つとして扱って引き渡すため,「echo_arg.sh "a b" c」と実行したのと同じになる。よって引数は「a b」と「c」の2つになる。