Bem, se "$@"
expande para a lista de parâmetros posicionais, um argumento por parâmetro posicional.
Quando você faz:
set '' 'foo bar' $'blah\nblah'
cmd "$@"
cmd
está sendo invocado com esses 3 argumentos: a string vazia foo bar
e blah<newline>blah
. O shell chamará a chamada do execve()
sistema com algo como:
execve("/path/to/cmd", ["cmd", "", "foo bar", "blah\nblah"], [envvars...]);
Se você deseja reconstruir uma linha de comando do shell (que é código na linguagem do shell) que reproduz a mesma chamada, você pode fazer algo como:
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 "$@"
Ou zsh
, solicitando diferentes tipos de citações:
$ 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'
Ou com zsh
, bash
ou ksh93
(aqui para bash
YMMV com outras conchas):
$ set '' 'foo bar' $'blah\nblah'
$ printf cmd; printf ' %q' "$@"; printf '\n'
cmd '' foo\ bar $'blah\nblah'
Você também pode usar a opção xtrace do shell, que faz com que o shell imprima o que será executado:
$ (PS4=; set -x; : cmd "$@")
: cmd '' 'foo bar' 'blah
blah'
Acima, executamos o :
comando no-op com cmd
e os parâmetros posicionais como argumento. Meu shell os imprimiu de uma maneira agradável e citada, adequada para reintroduzir no shell. Nem todas as conchas fazem isso.
$
expansões e outras aspas duplas. É por isso que as outras respostas usam aspas simples, enquanto se esforçam para lidar com aspas simples dentro da string, ou usam os próprios recursos do shell para produzir uma cópia citada da string.