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

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動
(ページの作成:「== 概要 == コマンドライン引数とは、シェルスクリプト実行時に渡される値のことである。<br> 引数は実行時にシェルスクリプ…」)
 
67行目: 67行目:
  #!/bin/bash
  #!/bin/bash
   
   
  echo '$1 =' "${1:-AAA}"
  echo '$1 =' "${1:-100}"
  echo '$2 =' "${2:-BBB}"
  echo '$2 =' "${2:-200}"
  echo '$3 =' "${3:-CCC}"
  echo '$3 =' "${3:-300}"
  </source>
  </source>
<br>
<br>
  # 実行結果
  # 実行結果
  ./sample.sh 100
  ./sample.sh 500
   
   
  $1 = 100
  $1 = 500
  $2 = BBB
  $2 = 200
  $3 = CCC
  $3 = 300
<br><br>
<br><br>



2020年8月11日 (火) 04:50時点における版

概要

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

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/bash
 
 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つのスペースに纏められてしまう。


デフォルト値を指定する

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

 #!/bin/bash
 
 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/bash
 
 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/bash
 
 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/bash
 
 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/bash
 
 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; ...