本文へ移動
vast-cowのブログ
前のページへ戻る

シェルスクリプトにおける `$@`, `$*`, `"$@"`, `"$*"` の違いを徹底解説

この記事を編集

シェルスクリプトで引数を扱う際、$@ や $* は頻繁に登場します。しかし、クォートの有無によって挙動が大きく変わるため、正確に理解していないとバグの原因になります。本記事では、それぞれの違いを具体例とともに整理します。


前提:位置パラメータとは

シェルスクリプトにおいて、コマンドライン引数は以下のように扱われます。

./script.sh foo bar "baz qux"

このとき:

そして、すべての引数をまとめて扱うのが $@ と $* です。


結論サマリ

書き方意味挙動
$@全引数単語分割される
$*全引数単語分割される
"$@"全引数各引数を個別に保持(最重要)
"$*"全引数1つの文字列に結合

$@ と $*(クォートなし)

for arg in $@; do
  echo "$arg"
done
for arg in $*; do
  echo "$arg"
done

挙動

どちらもほぼ同じで、「空白で分割された単語列」として展開されます。

問題点

./script.sh "hello world"

この場合:

つまり、元の引数の構造が壊れるため、実務ではほぼ使いません。


"$@"(最も重要)

for arg in "$@"; do
  echo "$arg"
done

挙動

例

./script.sh foo "bar baz"

出力:

foo
bar baz

特徴

👉 シェルスクリプトで引数を扱うときは基本これを使う


"$*"(1つの文字列に結合)

echo "$*"

挙動

例

./script.sh foo "bar baz"

出力:

foo bar baz

注意点


違いを図で理解

入力:

./script.sh A "B C" D

展開結果

書き方展開結果
$@A B C D
$*A B C D
"$@"”A” “B C” “D”
"$*"”A B C D”

よくあるバグパターン

❌ NG例

for arg in $@; do
  cp "$arg" /dest/
done

→ スペースを含むファイル名で壊れる


✅ 正しい書き方

for arg in "$@"; do
  cp "$arg" /dest/
done

実務での使い分け

基本ルール


まとめ

👉 シェルスクリプトで引数処理を書くなら "$@" をデフォルトにするべき


補足:なぜ違いがあるのか

これはシェルの「単語分割(word splitting)」と「クォート」の仕様に由来します。 特に "$@" は特殊な展開で、各引数が個別に保持される点が他と決定的に異なります。


この記事を編集
この記事を共有:

コメント


前の記事
rclone mountを快適に使うための、お気に入り設定
次の記事
WSL1 の DNS 問題を回避する方法