変数 ${@+"$@"} はどのような場面で役立つのか
ブルース・ブリン書「入門UNIXシェルプログラミング」の「2.5 位置パラメタ」にて以下のような記述がありました。
一般的には、前節で説明した
${variable+value}
の形式を使うのが最適でしょう。${@+"$@"}
こう書くことで、位置パラメタに何もセットされていない場合には何もしない、という条件を作れます。
参考までに記しておきますが、以下のように記述すると、あるシェルスクリプトに渡した引数を、まったくそのままの形で別の command というコマンドに渡す書き方になります。command ${@+"$@"}
あるいは、次のように書いてもいいでしょう。
if [ $# -eq 0]; then command else command "$@" fi
$@
は引数全体を表す特殊変数であり、${@+"$@"}
はスクリプトに引数が渡されていない場合は $@
として、引数が渡されている場合は "$@"
として動作する書き方です。
これを確認するために、以下のような引数をそのまま出力するシェルスクリプトを用意しました。
[~]$ cat atvars.sh
#!/bin/sh
echo "length=$#"
ruby -e "p ARGV" $@
ruby -e "p ARGV" "$@"
ruby -e "p ARGV" ${@+"$@"}
このスクリプトに引数を渡して、どのように動作するのか確認してみます。
(macOS および Debian9.9 の /bin/{sh,bash}
にて確認。すべて同じ出力でした)
~$ chmod u+x ./atvars.sh
~$ ./arvars.sh 123 "hello world"
length=2
["123", "hello", "world"]
["123", "hello world"]
["123", "hello world"]
~$ ./atvars.sh ""
length=1
[]
[""]
[""]
~$ ./atvars.sh
length=0
[]
[]
[]
この結果だけを見ると "$@"
と ${@+"$@"}
は同じ動作をしているように思えました。
それならば常に "$@"
を使う方が(書き方も短いし)良さげに思えるのですが、${@+"$@"}
が役に立つのはどういった場面が考えられるのでしょうか? それとも sh/bash や sh のバージョンの違いによって挙動が異なることを考慮しての記法なのでしょうか?