Bem, "$@"
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 chamado com esses 3 argumentos: a string vazia, foo bar
e blah<newline>blah
. O shell chamará a chamada do sistema execve()
com algo como:
execve("/path/to/cmd", ["cmd", "", "foo bar", "blah\nblah"], [envvars...]);
Se você quiser reconstruir uma linha de comando do shell (que é o código na linguagem shell) que reproduziria a mesma invocação, você poderia 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 com zsh
, pedindo 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 imprimiu-os de uma forma agradável e adequada para reintroduzir o shell. Nem todas as conchas fazem isso.