「シェルスクリプトの基礎 - コマンドライン引数」の版間の差分

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動
編集の要約なし
63行目: 63行目:
echoの引数として変数を渡す場合は、"$1"のようにダブルクォートで囲む癖をつける。<br>
echoの引数として変数を渡す場合は、"$1"のようにダブルクォートで囲む癖をつける。<br>
$1のようにそのまま記述すると、値として連続するスペースが含まれていた時に1つのスペースに纏められてしまう。<br>
$1のようにそのまま記述すると、値として連続するスペースが含まれていた時に1つのスペースに纏められてしまう。<br>
<br>
以下に、コマンドライン引数のを使用した応用例を示す。<br>
シェルスクリプトが2つ以上のパラメータを必要としている場合、シェルスクリプトの先頭で以下のように確認する。<br>
<syntaxhighlight lang="sh">
# 例 : 2つ以上のパラメータが必要な場合
#!/bin/bash
if [ $# -lt 2 ]; then
    echo "Usage: $(basename $0) <file1> <file2>" >&2
    exit -1
fi
</syntaxhighlight>
<br>
以下の例に、様々なコマンドライン引数の確認方法を示す。<br>
<syntaxhighlight lang="sh">
# 例 : 1つ以上のコマンドライン引数が必要な場合
#!/bin/bash
if [ ! "$1" ]; then
    echo "Usage: $(basename $1) <file>" >&2
    exit -1
fi
</syntaxhighlight>
<br>
<syntaxhighlight lang="sh">
# 例 : 1つ以上の引数が必要かつ特定のファイルが存在する場合
#!/bin/bash
# 引数の確認
if [ ! "$1" ]; then
    echo "Usage: $(basename $0) <file>" >&2
    exit -1
fi
# ファイルの存在の確認
if [ ! -f "$1" ]; then
    echo "$1 is not found" >&2
    exit -1
fi
</syntaxhighlight>
<br><br>
<br><br>



2020年11月29日 (日) 03:44時点における版

概要

コマンドライン引数とは、シェルスクリプト実行時に渡される値のことである。

引数は実行時にシェルスクリプト内で参照され、シェルスクリプトの実行結果に影響を与える。
引数はパラメータと呼ばれることもある。

command 引数1 引数2 … 引数n


引数処理に使用する変数
シェルスクリプト実行時に指定された引数は、位置パラメータと呼ばれる特殊な変数に自動的に設定される。
シェルスクリプト内からは、この変数を参照することで、引数を処理することが可能になる。
位置パラメータ以外にも、引数の処理に関連した特殊な変数がいくつかあり、 これらを組み合わせて使用することによって柔軟に引数を処理することが可能になる。

特殊変数名 自動的に設定される値
$# 実行時に指定された引数の数を表す変数。
「$ ./sample.sh AAA BBB CCC」を実行した場合、sample.sh内で変数$#を参照するとその値は3となる。
$@ シェルスクリプト実行時またはsetコマンド実行時に指定された全パラメータが設定される変数である。
変数$*と基本的に同じだが、""で囲んだ時の動作が異なる。
$* シェルスクリプト実行時またはsetコマンド実行時に指定された全パラメータが設定される変数である。
変数$@と基本的に同じだが、""で囲んだ時の動作が異なる。
$0 実行時のコマンド名が設定される変数である。
./sample.sh(/home/user/sample.sh)を実行した場合、/home/user/sample.shが設定される。
$1 - $n シェルスクリプト実行時に指定した各パラメータの値が設定される変数である。
1番目に指定した引数は$1、2番目に指定した引数は$2、n番目に指定した引数は$nに設定される。
10番目以降の引数参照時は${10}のように{}を使用する必要がある。
これは、$10を$1 "0"のように、シェルに誤った解釈をされることを防ぐためである。



パラメータ取得の基本

シェルスクリプト実行時にコマンドラインで渡したパラメータは、以下のような特殊変数で参照できる。

$1 – 第1パラメータ
$2 – 第2パラメータ
$3 – 第3パラメータ


パラメータの取得には、$1〜$9が使用できる。
10番目以降のパラメータを参照する場合は、${10}のように数値を{}で囲めば参照できる。

 #!/bin/sh
 
 echo '$1 =' "$1"
 echo '$2 =' "$2"
 echo '$3 =' "$3"


# 実行
./sample.sh AAA BBB "CCC  DDD"

# 出力
$1 = AAA
$2 = BBB
$3 = CCC  DDD


パラメータを指定しない場合は、対応する変数は空になる。

# 実行
./sample.sh AAA BBB

# 出力
$1 = AAA
$2 = BBB
$3 =


echoの引数として変数を渡す場合は、"$1"のようにダブルクォートで囲む癖をつける。
$1のようにそのまま記述すると、値として連続するスペースが含まれていた時に1つのスペースに纏められてしまう。

以下に、コマンドライン引数のを使用した応用例を示す。
シェルスクリプトが2つ以上のパラメータを必要としている場合、シェルスクリプトの先頭で以下のように確認する。

 # 例 : 2つ以上のパラメータが必要な場合
 #!/bin/bash
 
 if [ $# -lt 2 ]; then
    echo "Usage: $(basename $0) <file1> <file2>" >&2
    exit -1
 fi


以下の例に、様々なコマンドライン引数の確認方法を示す。

 # 例 : 1つ以上のコマンドライン引数が必要な場合
 #!/bin/bash
 
 if [ ! "$1" ]; then
    echo "Usage: $(basename $1) <file>" >&2
    exit -1
 fi


 # 例 : 1つ以上の引数が必要かつ特定のファイルが存在する場合
 #!/bin/bash
 
 # 引数の確認
 if [ ! "$1" ]; then
    echo "Usage: $(basename $0) <file>" >&2
    exit -1
 fi
 
 # ファイルの存在の確認
 if [ ! -f "$1" ]; then
    echo "$1 is not found" >&2
    exit -1
 fi



デフォルト値を指定する

パラメータが指定されなかった時のために、デフォルト値を指定しておくこともできる。
下記の例では、1番目、2番目、3番目のパラメータの初期値を、それぞれ、100、200、300 に設定している。

 #!/bin/sh
 
 echo '$1 =' "${1:-100}"
 echo '$2 =' "${2:-200}"
 echo '$3 =' "${3:-300}"


# 実行
./sample.sh 500

# 出力
$1 = 500
$2 = 200
$3 = 300



パラメータを反復処理で順番に処理する($@ と $*)

for文を使用する方法

シェルスクリプト実行時に渡されたパラメータは、特殊変数$@を使用して参照することができる。
以下の例では、for文を使用して、$@の要素を1つずつ抽出して処理している。(カウンタ変数$countをインクリメントしながらループしている)

 #!/bin/sh
 
 count=1
 for arg in "$@"
 do
    echo "$count: $arg"
    let count=$count+1
 done


# 実行
./sample.sh AAA BBB CCC

# 出力
1: AAA
2: BBB
3: CCC


また、特殊変数の指定部分in "$@"は省略して記述することができる。
明示的にin "$@"を記述する場合は、$@の部分をダブルクォーテーションで囲むことに注意する。

 #!/bin/sh
 
 count=1
 
 for arg
 do
    echo "$count: $arg"
    let count=$count+1
 done


while文を使用する方法

shiftコマンドを実行することで、$1〜$9に格納されたパラメータを1つずつ前にシフトすることができる。
shiftコマンドを実行する度に、$1に格納されていたパラメータは破棄され、パラメータ数を表す$#の値が1つずつ減っていく。

下記の例では、パラメータ数($#)が1以上の間、処理を続けるwhile文を定義している。
$1はパラメータの最初の要素を参照する変数であるが、直後のshiftによってパラメータを1つずつシフトしているので、
結果として、全てのパラメータを順番に参照することができる。

 #!/bin/sh
 
 count=1
 
 while [ "$#" -ge "1" ]
 do
    echo "$count: $1"
    shift
    let count=$count+1
 done


# 実行
./sample.sh AAA BBB CCC

# 出力
1: AAA
2: BBB
3: CCC



$@ と $* の違い

$@と似た特殊変数に$*が存在する。どちらもパラメータ全体を表す特殊変数であるが、
$@が各パラメータを個別に保持しているのに対し、$*は全てのパラメータを結合した1つの文字列である。
それぞれ、ダブルクォートで囲んで参照した場合と、囲まずに参照した場合の展開方法も含めて理解する。

 #!/bin/sh
 
 echo '=== Pattern 1 ==='
 for arg in "$@"
 do
    echo "$arg"
 done
 
 echo -e '\n=== Pattern 2 ==='
 for arg in $@
 do
    echo "$arg"
 done
 
 echo -e '\n=== Pattern 3 ==='
 for arg in "$*"
 do
    echo "$arg"
 done
 
 echo -e '\n=== Pattern 4 ==='
 for arg in $*
 do
    echo "$arg"
 done


# 実行
./sample.sh "100 200" "CCC DDD"

# 出力
=== Pattern 1 ===
100 200
CCC DDD

=== Pattern 2 ===
100
200
CCC
DDD

=== Pattern 3 ===
100 200 CCC DDD

=== Pattern 4 ===
100
200
CCC
DDD


Pattern 1の方法は、"$@"と指定することで、内部的には下記のように各要素を""で囲んで指定されたものとみなされるため、
正しく2つのパラメータとしてハンドルされる。

for arg in "100 200" "AAA BBB"; ...


Pattern 2の方法は、$@を""で囲まずに渡すと、下記のように各要素が展開して指定されたものとみなされる。
for文はスペース区切りで各要素が渡されていると判断するため、結果的に4つの要素として処理される。

for arg in 100 200 AAA BBB; ...


Pattern 3の方法は、"$*"と指定すると、下記のように全てのパラメータをスペースで繋げて、
更に全体を""で囲んで指定されたものとして処理される。
つまり、for文は、"100 200 AAA BBB"という文字列の1回分しか回らない。

for arg in "100 200 AAA BBB"; do


Pattern 4の方法は、$*と指定した場合は、Pattern 2と同様に、全ての要素がスペース区切りで渡されたとみなされる。(4つの要素として処理される)

for arg in 100 200 AAA BBB; ...



shiftコマンドによる引数の操作

shiftコマンドは、シェルスクリプトに渡した引数を順番に処理することができる。

上記のセクションに記述した通り、シェルスクリプトに渡した引数は、$1や$2等の特殊変数として扱われる。
shiftコマンドを使用すると、この特殊変数を順番にずらすことができる。
したがって、shiftコマンドを実行すると、$2の値は$1に代入され、$3の値は$2に代入されるといった変数の値をシフトすることができる。

以下の例では、shiftコマンドを実行して$1の値を出力し続けている。
shiftコマンドにより、3つの引数が順番にシフトされている。

 #!/bin/sh
 
 # $1が空になるまで繰り返し
 while [ -n "$1" ]
 do
    echo "param = $1"
    shift
 done

 # 実行
 ./test-shift.sh a b c
 
 # 出力
 param = a
 param = b
 param = c