abc()
スクリプトに渡される引数の分析に関連するロジックを処理する関数があるとします。
Bash スクリプトが受け取ったすべての引数を に渡すにはどうすればよいですかabc()
? 引数の数は可変であるため、渡された引数を次のようにハードコードすることはできません。
abc $1 $2 $3 $4
さらに良いことに、関数がスクリプト引数の変数にアクセスする方法はありますか?
ベストアンサー1
変数$@
は、スペースで区切られたすべてのコマンドライン パラメータに展開されます。次に例を示します。
abc "$@"
を使用する場合は$@
、スペースやワイルドカードを含む引数の誤解析を避けるために、(ほぼ)常に二重引用符で囲む必要があります (下記参照)。これは複数の引数に対して機能します。また、すべての POSIX 準拠シェルに移植可能です。
$0
また、(通常はスクリプトの名前またはパス) が に含まれていないことにも注意してください$@
。
のBash リファレンスマニュアル 特殊パラメータセクションは、1 から始まる位置パラメータに展開されることを示します$@
。展開が二重引用符内で行われる場合、各パラメータは別々の単語に展開されます。つまり、は"$@"
と同等です"$1" "$2" "$3"...
。
いくつかの引数を渡します:
最初の引数以外の引数をすべて渡す場合は、まず を使用してshift
最初の引数を「消費」し、次に"$@"
を渡して残りの引数を別のコマンドに渡します。Bash (および zsh と ksh、ただし dash などのプレーンな POSIX シェルでは不可) では、配列スライスのバリエーションを使用して引数リストを変更せずにこれを行うことができます。 は、"${@:3}"
で始まる引数を取得します"$3"
。"${@:3:4}"
は、 で始まる最大 4 つの引数"$3"
(つまり"$3" "$4" "$5" "$6"
) を取得します (それだけの引数が渡された場合)。
おそらくやりたくないこと:
"$*"
は、すべての引数を 1 つの文字列にまとめます (スペースで区切るか、または の最初の文字で区切ります)。これにより、引数内のスペースと引数間のスペース$IFS
の区別が失われるため、一般的には良い考えではありません。ただし、引数内/引数間のスペースの区別を維持する必要がない場合は、たとえば のように引数を印刷する場合は問題ないかもしれません。echo "$*"
引数を通常の変数に割り当てると( のようにargs="$@"
)、 のようにすべての引数がまとめられます"$*"
。 引数を変数に格納する場合は、 で配列を使用しargs=("$@")
(括弧で囲むことで配列になります)、"${args[0]}"
などとして参照します。 Bash と ksh では、配列のインデックスは 0 から始まるため、など$1
では になりますargs[0]
。 一方、zsh では、配列のインデックスは 1 から始まるため、 では$1
になりますargs[1]
。 また、dash などのより基本的なシェルには、配列がまったくありません。
$@
またはのいずれかを使用して二重引用符を省略すると、$*
各引数を個別の単語に分割しようとします ( 内の空白またはその他に基づいて$IFS
)。また、ファイル名のワイルドカードのように見えるものを、一致するファイル名のリストに展開しようとします。これは非常に奇妙な効果をもたらす可能性があるため、ほとんどの場合は避ける必要があります。 (zsh では、この展開はデフォルトで行われません。)