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

📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

編集の要約なし
文字列「__FORCETOC__」を「{{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This pag…
 
(同じ利用者による、間の6版が非表示)
36行目: 36行目:
パラメータの取得には、$1〜$9が使用できる。<br>
パラメータの取得には、$1〜$9が使用できる。<br>
10番目以降のパラメータを参照する場合は、${10}のように数値を{}で囲めば参照できる。<br>
10番目以降のパラメータを参照する場合は、${10}のように数値を{}で囲めば参照できる。<br>
  <source lang="sh">
  <syntaxhighlight lang="sh">
  #!/bin/sh
  #!/bin/sh
   
   
42行目: 42行目:
  echo '$2 =' "$2"
  echo '$2 =' "$2"
  echo '$3 =' "$3"
  echo '$3 =' "$3"
  </source>
  </syntaxhighlight>
<br>
<br>
  # 実行
  # 実行
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>


68行目: 108行目:
パラメータが指定されなかった時のために、デフォルト値を指定しておくこともできる。<br>
パラメータが指定されなかった時のために、デフォルト値を指定しておくこともできる。<br>
下記の例では、1番目、2番目、3番目のパラメータの初期値を、それぞれ、100、200、300 に設定している。<br>
下記の例では、1番目、2番目、3番目のパラメータの初期値を、それぞれ、100、200、300 に設定している。<br>
  <source lang="sh">
  <syntaxhighlight lang="sh">
  #!/bin/sh
  #!/bin/sh
   
   
74行目: 114行目:
  echo '$2 =' "${2:-200}"
  echo '$2 =' "${2:-200}"
  echo '$3 =' "${3:-300}"
  echo '$3 =' "${3:-300}"
  </source>
  </syntaxhighlight>
<br>
<br>
  # 実行
  # 実行
89行目: 129行目:
シェルスクリプト実行時に渡されたパラメータは、特殊変数$@を使用して参照することができる。<br>
シェルスクリプト実行時に渡されたパラメータは、特殊変数$@を使用して参照することができる。<br>
以下の例では、for文を使用して、$@の要素を1つずつ抽出して処理している。(カウンタ変数$countをインクリメントしながらループしている)<br>
以下の例では、for文を使用して、$@の要素を1つずつ抽出して処理している。(カウンタ変数$countをインクリメントしながらループしている)<br>
  <source lang="sh">
  <syntaxhighlight lang="sh">
  #!/bin/sh
  #!/bin/sh
   
   
98行目: 138行目:
     let count=$count+1
     let count=$count+1
  done
  done
  </source>
  </syntaxhighlight>
<br>
<br>
  # 実行
  # 実行
110行目: 150行目:
また、特殊変数の指定部分<code>in "$@"</code>は省略して記述することができる。<br>
また、特殊変数の指定部分<code>in "$@"</code>は省略して記述することができる。<br>
明示的にin "$@"を記述する場合は、$@の部分をダブルクォーテーションで囲むことに注意する。<br>
明示的にin "$@"を記述する場合は、$@の部分をダブルクォーテーションで囲むことに注意する。<br>
  <source lang="sh">
  <syntaxhighlight lang="sh">
  #!/bin/sh
  #!/bin/sh
   
   
120行目: 160行目:
     let count=$count+1
     let count=$count+1
  done
  done
  </source>
  </syntaxhighlight>
<br>
<br>
===== while文を使用する方法 =====
===== while文を使用する方法 =====
129行目: 169行目:
$1はパラメータの最初の要素を参照する変数であるが、直後のshiftによってパラメータを1つずつシフトしているので、<br>
$1はパラメータの最初の要素を参照する変数であるが、直後のshiftによってパラメータを1つずつシフトしているので、<br>
結果として、全てのパラメータを順番に参照することができる。<br>
結果として、全てのパラメータを順番に参照することができる。<br>
  <source lang="sh">
  <syntaxhighlight lang="sh">
  #!/bin/sh
  #!/bin/sh
   
   
140行目: 180行目:
     let count=$count+1
     let count=$count+1
  done
  done
  </source>
  </syntaxhighlight>
<br>
<br>
  # 実行
  # 実行
155行目: 195行目:
$@が各パラメータを個別に保持しているのに対し、$*は全てのパラメータを結合した1つの文字列である。<br>
$@が各パラメータを個別に保持しているのに対し、$*は全てのパラメータを結合した1つの文字列である。<br>
それぞれ、ダブルクォートで囲んで参照した場合と、囲まずに参照した場合の展開方法も含めて理解する。<br>
それぞれ、ダブルクォートで囲んで参照した場合と、囲まずに参照した場合の展開方法も含めて理解する。<br>
  <source lang="sh">
  <syntaxhighlight lang="sh">
  #!/bin/sh
  #!/bin/sh
   
   
181行目: 221行目:
     echo "$arg"
     echo "$arg"
  done
  done
  </source>
  </syntaxhighlight>
<br>
<br>
  # 実行
  # 実行
221行目: 261行目:
Pattern 4の方法は、$*と指定した場合は、Pattern 2と同様に、全ての要素がスペース区切りで渡されたとみなされる。(4つの要素として処理される)<br>
Pattern 4の方法は、$*と指定した場合は、Pattern 2と同様に、全ての要素がスペース区切りで渡されたとみなされる。(4つの要素として処理される)<br>
  for arg in 100 200 AAA BBB; ...
  for arg in 100 200 AAA BBB; ...
<br><br>
== ラッパー ==
シェルスクリプトの実行時の引数を、そのまま別のコマンドに渡す場合、<code>"$@"</code>を使用する。<br>
このような用途で記述されているシェルスクリプトのことをラッパーと呼ぶ。<br>
<syntaxhighlight lang="sh">
#!/bin/sh
./do_command.sh "$@"
</syntaxhighlight>
<br><br>
<br><br>


232行目: 282行目:
以下の例では、<code>shift</code>コマンドを実行して$1の値を出力し続けている。<br>
以下の例では、<code>shift</code>コマンドを実行して$1の値を出力し続けている。<br>
<code>shift</code>コマンドにより、3つの引数が順番にシフトされている。<br>
<code>shift</code>コマンドにより、3つの引数が順番にシフトされている。<br>
  <source lang="sh">
  <syntaxhighlight lang="sh">
  #!/bin/sh
  #!/bin/sh
   
   
249行目: 299行目:
  param = b
  param = b
  param = c
  param = c
  </source>
  </syntaxhighlight>
<br><br>
 
== コマンドライン引数の解析 : getopts ==
複雑なコマンドライン引数の指定する場合、全てのコマンドライン引数の妥当性の確認等、解析にはかなりの労力を要する。<br>
そのため、<code>getopts</code>コマンドを使用することで、コマンドライン引数の解析を容易に行うことができる。<br>
<br>
以下の例のように、コマンドライン引数の解析には、<code>while文</code>と<code>getopts</code>コマンドを組み合わせて使用する。<br>
<code>getopts</code>コマンドの第1引数には、シェルスクリプトに指定可能な引数名を指定して、その引数が値を要する場合は<code>:</code>(コロン)を付加する。<br>
第2引数には、解析に使用する任意の変数名を指定する。あくまでも変数名であるので、<code>$</code>を付ける必要はない。<br>
<br>
以下の例において、xxx.sh -a -b "BBB" -c "CCC"といったコマンドを実行する時、"BBB"および"CCC"等の値は変数<code>OPTARG</code>に代入される。<br>
<syntaxhighlight lang="sh">
#!/usr/bin/env sh
while getopts ab:c: OPT
do
    case $OPT in
      "a" )
          FLG_A="TRUE"
          ;;
      "b" )
          FLG_B="TRUE"
          VALUE_B="$OPTARG"
          ;;
      "c" )
          FLG_C="TRUE"
          VALUE_C="$OPTARG"
          ;;
    esac
done
</syntaxhighlight>
<br>
以下の例では、<code>getopts</code>コマンドを利用したシェルスクリプトを作成している。<br>
<syntaxhighlight lang="sh">
# param_getopts.shファイル
#!/usr/bin/env sh
CMDNAME=`basename $0`
while getopts ab:c: OPT
do
    case $OPT in
      "a" )
          FLG_A="TRUE"
          ;;
      "b" )
          FLG_B="TRUE"
          VALUE_B="$OPTARG"
          ;;
      "c" )
          FLG_C="TRUE"
          VALUE_C="$OPTARG"
          ;;
      * )
          echo "Usage: $CMDNAME [-a] [-b VALUE] [-c VALUE]" 1>&2
          exit 1
          ;;
    esac
done
if [ "$FLG_A" = "TRUE" ]; then
    echo '"-a"オプションが指定されました'
fi
if [ "$FLG_B" = "TRUE" ]; then
    echo '"-b"オプションが指定されました'
    echo "値は$VALUE_Bです"
fi
if [ "$FLG_C" = "TRUE" ]; then
    echo '"-c"オプションが指定されました'
    echo "値は$VALUE_Cです"
fi
exit 0
# 実行
./param_getopts.sh  # 引数の指定が無い場合、何も出力せずに終了する
./param_getopts.sh -a
./param_getopts.sh -a -b "123456"
./param_getopts.sh -ab "123456"  # -abのように複数のオプションをまとめて指定することも可能
./param_getopts.sh -a -b "123456" -c  # -cオプションに値が指定されていないためエラー
./param_getopts.sh -a -b "123456" -c "ABCDEF"
# 出力
"-a"オプションが指定されました
"-a"オプションが指定されました
"-b"オプションが指定されました
値は123456です
"-a"オプションが指定されました
"-b"オプションが指定されました
値は123456です
./param_getopts.sh: option requires an argument -- c
Usage: param_getopts.sh [-a] [-b VALUE] [-c VALUE]
"-a"オプションが指定されました
"-b"オプションが指定されました
値は123456です
"-c"オプションが指定されました
値はABCDEFです
</syntaxhighlight>
<br><br>
<br><br>
== getoptsコマンドとshiftコマンドの組み合わせ ==
複雑なコマンドライン引数の指定が必要なシェルスクリプトの場合、<br>
引数の解析後に不要となった引数に対して、<code>shift</code>コマンドで切り捨てることができる。<br>
<br>
以下の例では、変数<code>OPTIND</code>から1を引いた分だけ<code>shift</code>コマンドを実行することにより、不要になった引数を切り捨てている。<br>
<syntaxhighlight lang="sh">
shift $(expr $OPTIND - 1)
</syntaxhighlight>
<br>
変数<code>OPTIND</code>は、<code>getopts</code>コマンドがオプションを順番に処理するために使用するオプション位置を示すカーソルのような働きをする変数である。<br>
<code>getopts</code>コマンドの終了後は、変数<code>OPTIND</code>の値がオプションの直後を指し示しているため、<br>
この値から1減算した分だけ<code>shift</code>することにより、オプション部分を切り捨てることができる。<br>
<br>
以下の例では、シェルスクリプト内において、getopts abc OPTと記述されている場合、<code>getopts</code>コマンドの終了後の変数<code>OPTIND</code>の値は、<br>
<パラメータ>の位置を指し示している。<br>
その値から1減算して<code>shift</code>するということは、-a -b -cを切り捨てることになる。<br>
xxx.sh -a -b -c "<パラメータ>"
<br>
以下の例では、オプション部分を切り捨てるシェルスクリプトを作成している。<br>
どのようなコマンドライン引数であっても、オプション部分のみが確実に切り捨てていることが確認できる。<br>
<syntaxhighlight lang="sh">
#!/usr/bin/env sh
# -a, -b, -cオプションを指定可能とする
while getopts abc OPT
do
    # ...解析処理は省略
done
# オプション部分を切り捨てる
shift $(expr $OPTIND - 1)
# オプション部分を切り捨てたため、変数$1には先頭の引数が設定されている
echo "引数に\"$1\"が指定されました"
exit 0
# 実行
./param_optind.sh -abc "PARAMETER"
./param_optind.sh -ab "PARAMETER"
./param_optind.sh -ac "PARAMETER"
./param_optind.sh "PARAMETER"
./param_optind.sh -a -b -c "PARAMETER1" "PARAMETER2"
# 出力
引数に"PARAMETER"が指定されました
引数に"PARAMETER"が指定されました
引数に"PARAMETER"が指定されました
引数に"PARAMETER"が指定されました
引数に"PARAMETER1"が指定されました
</syntaxhighlight>
<br><br>
{{#seo:
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux
|image=/resources/assets/MochiuLogo_Single_Blue.png
}}


__FORCETOC__
__FORCETOC__
[[カテゴリ:シェルスクリプト]]
[[カテゴリ:シェルスクリプト]]