Ну, "$@"
расширяется до списка позиционных параметров, один аргумент на позиционный параметр.
Когда вы делаете:
set '' 'foo bar' $'blah\nblah'
cmd "$@"
cmd
вызывается с этими тремя аргументами: пустой строкой foo bar
и 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
позиционными параметрами в качестве аргумента. Моя оболочка напечатала их красивым цитируемым способом, подходящим для повторного ввода в оболочку. Не все оболочки делают это.
$
расширений и других двойных кавычек. Вот почему другие ответы используют одинарные кавычки при переходе на несколько длин для обработки одинарных кавычек внутри строки или используют собственные функции оболочки для создания цитируемой копии строки.