Cóż, "$@"
rozwija się do listy parametrów pozycyjnych, jeden argument na parametr pozycyjny.
Kiedy to zrobisz:
set '' 'foo bar' $'blah\nblah'
cmd "$@"
cmd
jest wywoływany z tymi 3 argumentami: pusty ciąg foo bar
i blah<newline>blah
. Powłoka wywoła wywołanie execve()
systemowe za pomocą czegoś takiego:
execve("/path/to/cmd", ["cmd", "", "foo bar", "blah\nblah"], [envvars...]);
Jeśli chcesz zrekonstruować wiersz poleceń powłoki (czyli kod w języku powłoki), który odtworzyłby to samo wywołanie, możesz zrobić coś takiego:
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 "$@"
Lub z zsh
pytaniem o różne typy cytatów:
$ 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'
Lub z zsh
, bash
lub ksh93
(tutaj dla bash
YMMV z innymi powłokami):
$ set '' 'foo bar' $'blah\nblah'
$ printf cmd; printf ' %q' "$@"; printf '\n'
cmd '' foo\ bar $'blah\nblah'
Możesz także użyć opcji xtrace powłoki, która powoduje, że powłoka drukuje to, co zamierza wykonać:
$ (PS4=; set -x; : cmd "$@")
: cmd '' 'foo bar' 'blah
blah'
Powyżej uruchomiliśmy polecenie :
no-op z cmd
parametrami pozycyjnymi jako argumentem. Moja skorupa wydrukowała je w ładny cytat, nadający się do ponownego włożenia do powłoki. Nie wszystkie muszle to robią.
$
rozwinięć i innych podwójnych cudzysłowów. Dlatego w innych odpowiedziach używane są pojedyncze cudzysłowy, a niektóre długości służą do obsługi pojedynczych cudzysłowów w ciągu lub wykorzystują własne funkcje powłoki do tworzenia cytowanej kopii łańcucha.