1. 序章

以前、コマンドライン引数をbashスクリプトに渡す方法を検討しました。 このチュートリアルでは、bashスクリプト内でこれらの引数を使用する方法を見ていきます。

2. 入力の処理

スクリプト内のbashスクリプトに渡された引数を処理するさまざまな方法を見てみましょう。

2.1. 位置パラメータ

スクリプトに渡された引数は、送信されたのと同じ順序で処理されます。 引数のインデックス付けは1から始まり、最初の引数は $1を使用してスクリプト内でアクセスできます。 同様に、2番目の引数には、 $ 2、などを使用してアクセスできます。 位置パラメーターは、引数の位置を使用して、引数のこの表現を参照します。

次のスクリプトuserReg-positional-parameter.shの例を見てみましょう。このスクリプトは、 username age 、および fullnameを出力します。この順序で:

echo "Username: $1";
echo "Age: $2";
echo "Full Name: $3";

次に、3つの入力パラメーターを使用してこのスクリプトを実行しましょう。

sh userReg-positional-parameter.sh john 25 'John Smith'

出力は次のようになります。

Username : john
Age: 25
Full Name: John Smith

2.2. フラグ

フラグの使用は、入力をスクリプトに渡す一般的な方法です。 スクリプトに入力を渡す場合、各引数の前にハイフン(-)で始まるフラグ(通常は1文字)があります。

userReg-flags.sh スクリプトを見てみましょう。このスクリプトは、 username(-u) age(-a)、および[ X135X]フルネーム(-f)。

以前のスクリプトを変更して、位置パラメーターに依存する代わりにフラグを使用します。 getopts 関数は入力のフラグを読み取り、OPTARGは対応する値を参照します。

while getopts u:a:f: flag
do
    case "${flag}" in
        u) username=${OPTARG};;
        a) age=${OPTARG};;
        f) fullname=${OPTARG};;
    esac
done
echo "Username: $username";
echo "Age: $age";
echo "Full Name: $fullname";

以前と同じ入力でこのスクリプトを実行してみましょう。今回は、入力にフラグを追加します。

sh userReg-flags.sh -f 'John Smith' -a 25 -u john

usernameおよびfullname 引数の位置をシフトしましたが、出力は以前と同じです。

Username : john
Age: 25
Full Name: John Smith

ここでは、 getopts 関数を使用して入力として提供されたフラグを解析し、caseブロックを使用して指定された値を対応する変数に割り当てています。

2.3. ループ構成

位置パラメータは、多くの場合便利ですが、入力サイズが不明な場合は使用できません。 ループ構造の使用は、これらの状況で役立ちます。

変数$@は、すべての入力パラメーターの配列です。 for ループ内でこの変数を使用すると、入力を反復処理して、渡されたすべての引数を処理できます。

入力として渡されたすべてのユーザー名を出力するスクリプトusers-loop.shの例を見てみましょう。

i=1;
for user in "$@" 
do
    echo "Username - $i: $user";
    i=$((i + 1));
done

次に、スクリプトを実行してみましょう。

sh users-loop.sh john matt bill 'joe wicks' carol

そして、出力が表示されます。

Username - 1: john
Username - 2: matt
Username - 3: bill
Username - 4: joe wicks
Username - 5: carol

上記の例では、入力パラメーターの配列全体に対してuser変数を繰り返し処理しています。 この反復は、最初の入力引数 john から始まり、入力のサイズが不明であっても、最後の引数carolまで実行されます。

2.4. シフト演算子

bashのシフト演算子(構文的には shift n 、ここで n は移動する位置の数)は、コマンドライン引数の位置をシフトします。 n のデフォルト値は、指定されていない場合は1です。

シフト演算子により、入力のインデックス作成はシフトされた位置から開始されます。 つまり、この演算子を配列入力で使用すると、位置パラメーター $ 1 は、位置パラメーターにバインドされている現在の引数からnの位置を右にシフトして到達した引数に変わります。 $1

入力が奇数か偶数かを判断するスクリプトの例を考えてみましょう。

sh parityCheck.sh 13 18 27 35 44 52 61 79 93

位置パラメータに関する上記の説明から、 $1が最初の引数である13を参照していることがわかります。 入力1( shift 1 )でシフト演算子を使用すると、インデックス付けは2番目の引数から開始されます。 つまり、 $ 1 は2番目の引数(18)を参照するようになりました。 同様に、 shift 2 を呼び出すと、4番目の引数(35)からインデックス作成が開始されます。

上で説明したユーザースクリプトの例をもう一度見てみましょう。 $ @ 変数を使用して反復する代わりに、シフト演算子を使用します。 $#変数は入力サイズを返します:

i=1;
j=$#;
while [ $i -le $j ] 
do
    echo "Username - $i: $1";
    i=$((i + 1));
    shift 1;
done

上記と同じ入力でスクリプトを実行してみましょう。

sh users-shift-operator.sh john matt bill 'joe wicks' carol

出力は以前と同じになります。

Username - 1: john
Username - 2: matt
Username - 3: bill
Username - 4: joe wicks
Username - 5: carol

この例では、入力の最後に到達するまで、各反復で位置パラメーターを1ずつシフトしています。 したがって、 $ 1 は、毎回入力の次の要素を参照します。

3. 結論

この記事では、実行時にbashスクリプトに渡された引数を、スクリプト内でさまざまな方法で処理する方法について説明しました。

  • 入力サイズが固定されており、入力内の引数の順序がわかっている場合は、位置パラメーターを使用できます。
  • フラグを使用すると、入力の引数の順序は重要ではありません。
  • ループ構造は、入力サイズが不明な場合に便利です。
  • シフト演算子を使用すると、シフトされた位置の引数からインデックスが開始されます。
  • 変数$@ は入力パラメーターの配列を返し、 $#は入力配列のサイズを返します。

いつものように、この記事で使用されている例は、GitHubから入手できます。