Bene, si "$@"
espande all'elenco dei parametri posizionali, un argomento per parametro posizionale.
Quando lo fai:
set '' 'foo bar' $'blah\nblah'
cmd "$@"
cmd
viene invocato con questi 3 argomenti: la stringa vuota foo bar
e blah<newline>blah
. La shell chiamerà la execve()
chiamata di sistema con qualcosa del tipo:
execve("/path/to/cmd", ["cmd", "", "foo bar", "blah\nblah"], [envvars...]);
Se vuoi ricostruire una riga di comando della shell (ovvero il codice nel linguaggio della shell) che riproduca la stessa invocazione, potresti fare qualcosa del tipo:
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 "$@"
O con zsh
, chiedendo diversi tipi di citazioni:
$ 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'
O con zsh
, bash
o ksh93
(qui per bash
, YMMV con altre shell):
$ set '' 'foo bar' $'blah\nblah'
$ printf cmd; printf ' %q' "$@"; printf '\n'
cmd '' foo\ bar $'blah\nblah'
Puoi anche usare l'opzione xtrace della shell che fa stampare alla shell ciò che sta per eseguire:
$ (PS4=; set -x; : cmd "$@")
: cmd '' 'foo bar' 'blah
blah'
Sopra, abbiamo eseguito il :
comando no-op con cmd
e i parametri posizionali come argomento. La mia conchiglia le ha stampate in modo gradevole e adatto per essere reintegrate nella conchiglia. Non tutte le shell lo fanno.
$
espansioni e altre virgolette doppie. Ecco perché le altre risposte usano virgolette singole mentre vanno in alcune lunghezze per gestire virgolette singole all'interno della stringa o utilizzare le funzionalità della shell per produrre una copia della stringa tra virgolette.