Bash Strict Modeを使用するときにBashスクリプトの位置パラメータを解析する方法は?

Bash Strict Modeを使用するときにBashスクリプトの位置パラメータを解析する方法は?

Bash 厳格モードは次のように定義されます。

#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

http://redsymbol.net/articles/unofficial-bash-strict-mode/

次のBashスクリプトで位置パラメータの解析を検討してください。

#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

usage() {
  echo ""
  echo "usage:"
  echo "$0 [options]"
  echo "  -r | --redirect-uri:  redirect uri"
  echo "  -a | --app-role:      app role id"
  echo "  -h | --help:          help"
  echo ""
}

redirect_uri=""
app_role=""

while [ "$1" != "" ]; do
  case $1 in
  -r | --redirect-uri)
    shift
    redirect_uri="$1"
    ;;
  -a | --app-role)
    shift
    app_role="$1"
    ;;
  -h | --help)
    usage
    exit 0
    ;;
  *)
    usage
    exit 1
    ;;
  esac
  shift
done

...

これは、次のエラーには適用されません。

$ ./app.sh -r https://example.net:8080/auth/callback -a 53b37b21-2c6e-4731-a5e5-15b98052c686        
./app.sh: line 18: $1: unbound variable

whileその理由は、条件の最終確認が定義されていないshiftためだと思います$1

Bash厳密モードを使用するときにwhileスクリプトを競合せずにステートメントでパラメータ解析を終了するにはどうすればよいですか?

答え1

ループの最後の反復の後には表示されない未定義の状態でアクセスunbound variableしようとするため、エラーが発生します。したがって、問題のコマンドは使用するテストです。$1whilewhile

[ "$1" != "" ]

代わりに、次のようなものを使用してください。

[ "${1+set}" = set ]

または

[ -n "${1+set}" ]

パラメータ拡張は、既存の変数の場合(null以外の値があるかどうかにかかわらず)${parameter+word}に拡張されます。この単語はランダムに選択されていますが、ある意味ではその目的を暗示しています。wordparameterset

$#位置パラメータの数が保存されているかどうかをテストすることもできます。

[ "$#" -ne 0 ]

または

[ "$#" -gt 0 ]

リストから処理して削除する必要がある場所パラメータがある限り、これらの算術テストは正確です。

nounsetこれらのバリエーションの1つは、シェルオプション()によって課される制限との競合を防ぎますset -u

関連情報