🔙 Back to Top

Tue Nov 14 2017

Bash 引数の文字列結合

勘違いをずっとしていたのでメモ

シェルスクリプト、あるいは関数で引数には $1, $2, ... でアクセスできる. $@ にすると、これら全てを配列として得ることができる. 配列を単に echo をすると、それらを空白1つで結合した文字列が出力されるので、可変数引数を簡単に扱うのに便利.

f() { echo $@ }
f 1 2 3
# => 1 2 3

ところでこの例だと、f() の中では echo 1 2 3 が実行されている. つまり echo コマンドに引数を3つ渡したことになっている.

$@ を "$@" とすれば、 echo "1 2 3" となって、引数を1つだけ渡すことになると思っていたが、これは誤りだったようだ.

引数の個数 ($@ の長さ) は $# でチェックできる.

f() {
    echo "f-args ($#): $@"
}

ng() {
    f "$@"
}

ok() {
    A="$@"
    f "$A"
}

ng a b  # => f-args (2): a b
ok a b  # => f-args (1): a b

ダブルクオーテーションで括っていようが、$@ にアクセスすると勝手に展開されるらしい. 上の ok はわざわざ変数に代入することで、f の引数を $A 1個にしてる.