さて、"$@"
定位置パラメーターのリストに展開されます(定位置パラメーターごとに1つの引数)。
あなたがするとき:
set '' 'foo bar' $'blah\nblah'
cmd "$@"
cmd
空の文字列foo bar
との3つの引数で呼び出されますblah<newline>blah
。シェルはexecve()
次のようなものでシステムコールを呼び出します:
execve("/path/to/cmd", ["cmd", "", "foo bar", "blah\nblah"], [envvars...]);
同じ呼び出しを再現するシェルコマンドライン(シェル言語のコード)を再構築する場合は、次のようにします。
awk -v q="'" '
function shellquote(s) {
gsub(q, q "\\" q q, s)
return q s q
}
BEGIN {
for (i = 1; i < ARGC; i++) {
printf "%s", sep shellquote(ARGV[i])
sep = " "
}
printf "\n"
}' cmd "$@"
またはでzsh
、さまざまなタイプの引用符を要求します。
$ set '' 'foo bar' $'blah\nblah'
$ print -r -- cmd "${(q)@}"
cmd '' foo\ bar blah$'\n'blah
$ print -r -- cmd "${(qq)@}"
cmd '' 'foo bar' 'blah
blah'
$ print -r -- cmd "${(qqq)@}"
cmd "" "foo bar" "blah
blah"
$ print -r -- cmd "${(qqqq)@}"
cmd $'' $'foo bar' $'blah\nblah'
またはzsh
、bash
またはksh93
(ここではbash
、他のシェルを使用するYMMV):
$ set '' 'foo bar' $'blah\nblah'
$ printf cmd; printf ' %q' "$@"; printf '\n'
cmd '' foo\ bar $'blah\nblah'
シェルのxtraceオプションを使用して、シェルが実行する内容を出力することもできます。
$ (PS4=; set -x; : cmd "$@")
: cmd '' 'foo bar' 'blah
blah'
上記では、位置パラメーターを引数として使用して:
no-opコマンドを実行しましたcmd
。私のシェルは、シェルへの再入力に適した、引用された方法でそれらを印刷しました。すべてのシェルがそうするわけではありません。
$
展開、およびその他の二重引用符の保護にはあまり役立ちません。そのため、他の回答では、文字列内の一重引用符を処理するためにある程度の長さを取りながら一重引用符を使用するか、文字列の引用符付きコピーを生成するためにシェル独自の機能を使用します。