Linuxシェルスクリプトを書く際、コマンドライン引数をどう扱うかは非常に重要なポイントです。特に、複数の引数を一括で処理したい場合に便利なのが、特殊変数の$*
です。しかし、$*
と"$*"
、さらには"$@"
との違いを正確に理解していないと、思わぬ挙動を引き起こす可能性もあります。
本記事では、$*
の基本的な使い方から、他の引数展開との違い、実際の使用例までをわかりやすく解説します。これからシェルスクリプトを始める初心者の方にも、すでにスクリプトを組んでいる方の復習にも役立つ内容です。
$*
は、スクリプトや関数に渡されたすべての引数を1つの文字列として展開する特殊変数です。言い換えれば、位置パラメータ$1
, $2
, $3
などをスペース区切りで連結したものが$*
になります。
#!/bin/bash
echo "引数一覧: $*"
このスクリプトに対して以下のように実行した場合:
./myscript.sh one two three
出力は以下の通りになります:
引数一覧: one two three
このように、$*
はすべての引数を「1つの文字列」として扱うため、簡単な表示やログ出力などに適しています。
よく似た変数に$@
がありますが、違いは引用符の有無と使い方で顕著に表れます。
たとえば、次の2つの例を見てみましょう。
#!/bin/bash
for arg in "$*"; do
echo "$arg"
done
このスクリプトを以下のように実行した場合:
./myscript.sh "one two" three
出力は:
one two three
つまり、全引数を1つの文字列として展開されているため、ループは1回しか実行されません。
#!/bin/bash
for arg in "$@"; do
echo "$arg"
done
同じコマンドで実行した場合:
./myscript.sh "one two" three
出力は:
one two
three
"$@"
はそれぞれの引数を個別の要素として扱うため、ループは引数の数だけ繰り返されます。
$*
が特に便利なのは、複数の引数を1つのログメッセージとしてまとめたい場合です。以下はログ出力の例です。
#!/bin/bash
log_message() {
echo "[INFO] $*"
}
log_message "ユーザーがログインしました" "ユーザーID: 123"
この出力は:
[INFO] ユーザーがログインしました ユーザーID: 123
このように$*
を使えば、複数の引数を1つの文にして記録できるため、シンプルなログ処理には非常に適しています。
$*
は「スペースで結合された1つの文字列」になるため、引数そのものにスペースが含まれると意図しない扱いになることがあります。
./myscript.sh "ファイル A.txt" "ファイル B.txt"
この場合、"$*"
として処理すると:
ファイル A.txt ファイル B.txt
一見問題なさそうに見えますが、これをループ処理などに使うと1回しかループされず、スペースのある引数が結合されてしまうため、誤動作の原因になります。
もしも引数を個別に扱いたい場合は、"$@"
を使うべきです。
$*
を使う場面では、以下のような場面に限るのが安全です。
以下のようなコーディングが有効です:
log_args() {
echo "処理された引数: $*"
}
逆に、個々の引数に対して処理を行う場合は、必ず"$@"
を使うようにしましょう。
$*
は、すべての引数を「1つの文字列」にまとめて処理するための便利な変数です。ログの記録や単純な出力には向いていますが、引数にスペースが含まれる場合や、それぞれの引数に対して処理を行いたい場合には不向きです。
同じように見える"$*"
と"$@"
も使い方次第で結果が大きく変わるため、目的に応じた使い分けが大切です。スクリプトの堅牢性を高めるためにも、これらの挙動をしっかり理解しておきましょう。