1. 概要

Linuxユーザーとして、私たちはさまざまなコマンドラインユーティリティとスクリプトを頻繁に使用します。 スクリプト開発中の一般的なタスクの1つは、コマンドラインオプションを解析することです。 これらのオプションは短くても長くてもかまいません。

このチュートリアルでは、bashのgetopts関数とgetoptユーティリティを使用してコマンドラインオプションを解析します。

2. getoptsを使用した短いコマンドラインオプションの解析

Bash では、短いコマンドラインオプションと長いコマンドラインオプションの両方を使用できます。 短いオプションは、単一のハイフン(-)文字とそれに続く単一の英数字で始まりますが、長いオプションは、ダブルハイフン(–)文字とそれに続く複数の文字で始まります。

ls コマンドに、非表示のファイルを表示するように指示できます。

$ ls -a
.  ..  hello.txt
$ ls --all
.  ..  hello.txt

上記の例では:

  • -aは短いオプションを表します
  • –allはロングオプションを表します

短いコマンドラインオプションを解析するには、bashの組み込み関数getoptsを使用できます。 オプションとして位置パラメータを解析します。

2.1. getopts構文

getopts関数の構文は次のとおりです。

getopts optstring opt [arg ...]

上記の関数では:

  • optstring は、サポートされているオプションを表します。 このオプションの後にコロン(:) がある場合、このオプションは引数を予期します。 たとえば、オプション c が引数を予期している場合、 optstringではc:として表されます。
  • オプションに引数が関連付けられている場合、getoptsは引数を文字列としてOPTARGシェル変数に格納します。 たとえば、オプション c に渡された引数は、OPTARG変数に格納されます。
  • opt には、解析されたオプションが含まれています。

次のセクションでは、これらの概念が実際に動作しているのを見ると明らかになります。

2.2. スクリプトでの使用例

簡単なシェルスクリプトを作成して、その使用法を確認しましょう。

#!/bin/bash

while getopts 'abc:h' opt; do
  case "$opt" in
    a)
      echo "Processing option 'a'"
      ;;

    b)
      echo "Processing option 'b'"
      ;;

    c)
      arg="$OPTARG"
      echo "Processing option 'c' with '${OPTARG}' argument"
      ;;
   
    ?|h)
      echo "Usage: $(basename $0) [-a] [-b] [-c arg]"
      exit 1
      ;;
  esac
done
shift "$(($OPTIND -1))"

スクリプトを実行して、出力を確認してみましょう。

$ chmod +x parse-command-line-args.sh

$ ./parse-command-line-args.sh -a 
Processing option 'a' 

$ ./parse-command-line-args.sh -c test-value
Processing option 'c' with 'test-value' argument 

$ ./parse-command-line-args.sh -ab 
Processing option 'a'
Processing option 'b'

2.3. getoptsでのエラー報告

getopts関数は2つのシナリオでエラーを報告します— 1つは無効なオプションが使用された場合、もう1つは引数が指定されていない場合です。

  • opt 変数には、無効なオプションが指定されている場合、疑問符(?)文字が含まれます
  • opt 変数には、必須の引数が指定されていない場合、コロン(:)文字が含まれます

これらのエラーシナリオの両方をキャッチし、ユーザーに適切なエラーメッセージを表示できます。 これらのシナリオを処理するようにスクリプトを変更してみましょう。

#!/bin/bash

while getopts ':abc:h' opt; do
  case "$opt" in
    a)
      echo "Processing option 'a'"
      ;;

    b)
      echo "Processing option 'b'"
      ;;

    c)
      arg="$OPTARG"
      echo "Processing option 'c' with '${OPTARG}' argument"
      ;;

    h)
      echo "Usage: $(basename $0) [-a] [-b] [-c arg]"
      exit 0
      ;;

    :)
      echo -e "option requires an argument.\nUsage: $(basename $0) [-a] [-b] [-c arg]"
      exit 1
      ;;

    ?)
      echo -e "Invalid command option.\nUsage: $(basename $0) [-a] [-b] [-c arg]"
      exit 1
      ;;
  esac
done
shift "$(($OPTIND -1))"

次に、スクリプトを実行してエラーメッセージを確認します。

$ ./parse-command-line-args.sh -c
option requires an argument.
Usage: parse-command-line-args.sh [-a] [-b] [-c arg]

$ ./parse-command-line-args.sh -e
Invalid command option.
Usage: parse-command-line-args.sh [-a] [-b] [-c arg]

optstringも更新したことに注意してください。 これで、デフォルトのエラーメッセージを抑制するcolon(:)文字で始まります。 これとは別に、 OPTERR エラー報告の動作を変更するための環境変数。 getopts 関数は、 OPTERR 変数がゼロに設定されている場合、エラー報告を無効にします。

3. getoptを使用した長いコマンドラインオプションの解析

読みやすさを向上させるために、長いコマンドラインオプションを使用すると便利な場合があります。  ただし、 getopts は、短いコマンドラインオプションのみをサポートします。 GNUのgetoptコマンドを使用して、長いコマンドラインオプションを解析できます

#!/bin/bash

VALID_ARGS=$(getopt -o abg:d: --long alpha,beta,gamma:,delta: -- "$@")
if [[ $? -ne 0 ]]; then
    exit 1;
fi

eval set -- "$VALID_ARGS"
while [ : ]; do
  case "$1" in
    -a | --alpha)
        echo "Processing 'alpha' option"
        shift
        ;;
    -b | --beta)
        echo "Processing 'beta' option"
        shift
        ;;
    -g | --gamma)
        echo "Processing 'gamma' option. Input argument is '$2'"
        shift 2
        ;;
    -d | --delta)
        echo "Processing 'delta' option. Input argument is '$2'"
        shift 2
        ;;
    --) shift; 
        break 
        ;;
  esac
done

上記のスクリプトでは:

  • -o optionは、短いコマンドラインオプションを表します
  • –long オプションは、長いコマンドラインオプションを表します

スクリプトを実行して、出力を確認してみましょう。

$ chmod +x parse-long-command-line-args.sh 
$ ./parse-long-command-line-args.sh -a
Processing 'alpha' option

$ ./parse-long-command-line-args.sh --alpha
Processing 'alpha' option

$ ./parse-long-command-line-args.sh --delta test-value
Processing 'delta' option. Input argument is 'test-value'

$ ./parse-long-command-line-args.sh -g test-value
Processing 'gamma' option. Input argument is 'test-value'

4. 結論

このチュートリアルでは、Linuxコマンドライン引数を解析するために使用できる2つの方法について説明しました。 最初に、bashの組み込み関数getoptsについて説明しました。 次に、GNUのgetoptコマンドについて説明しました。 これらの例を日常生活で使用して、シェルスクリプトをより堅牢にすることができます。