Чтобы настроить правильную среду сборки в Debian , используйте:
apt install module-assistant
ma prepare
Добавьте set -v
к вашей функции, и вы увидите, что происходит:
$ f (){ set -v; sudo -- sh -c "cd /tmp; echo \"$@\""; }
$ f 1 2
+ sudo -- sh -c 'cd /tmp; echo "1' '2"'
Что происходит? Использование вами $@
привело к созданию двух строк, заключенных в одинарные кавычки cd /tmp; эхо "1
и 2"
. Вы можете использовать $*
, если не хотите этого разбиения. См. раздел справочной страницы bash в Специальные параметры:
@ ... Когда расширение происходит в двойных кавычках, каждый параметр расширяется до отдельного слова. ... Если ... в слове расширение первый параметр соединяется с начальной частью исходного слова, и расширение последнего параметра соединяется с последней частью исходное слово.
Таким образом, в вашем случае одна строка (или слово) «xxx$@yyy» расширяется до двух строк «xxx1» и «2yyy». Вы можете проверить это, используя set -- 1 2 3
, чтобы установить $@
, а затем использовать printf ">%s<" "$@"
, чтобы увидеть количество слов, которое становится "$@"
(поскольку printf будет повторять формат для каждого аргумента):
$ set -- 1 2 3
$ printf ">%s< " "x$@y"
>x1< >2< >3y<
$ printf ">%s< " "x$*y"
>x1 2 3y<
Если вы хотите передать аргументы команде sh -c
один хак состоит в том, чтобы поместить их после одиночной команды в качестве аргументов, но это может работать не во всех оболочках:
f (){ set -v; sudo -- sh -c 'cd /tmp; echo "$@"' sh "$@"; }
f 1 2
+ sudo -- sh -c 'cd /tmp; echo "$@"' sh 1 2
Дополнительный аргумент sh
связан с тем, что первый аргумент принимается оболочкой как имя процесса.