Я написал сценарий, который может генерировать эти аргументы для меня, с кавычками
Если выходные данные правильно указаны для оболочки, и вы доверяете выходным данным , тогда вы можете запустить eval
их.
Предполагая, что у вас есть оболочка, которая поддерживает массивы, лучше всего использовать ее для хранения полученных аргументов.
Если ./gen_args.sh
выдает вывод, как 'foo bar' '*' asdf
, то мы можем запустить eval "args=( $(./gen_args.sh) )"
заполнить массив args
с результатами. Это было бы три элемента foo bar
, *
, asdf
.
Мы можем использовать "${args[@]}"
как обычно, чтобы расширить элементы массива индивидуально:
$ eval "args=( $(./gen_args.sh) )"
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
(Обратите внимание, что кавычки "${array[@]}"
распространяются на все элементы как отдельные аргументы без изменений. Без кавычек элементы массива могут быть разбиты на слова. См., Например, страницу «Массивы» в BashGuide .)
Тем не менее , eval
он с радостью выполнит любые замены оболочки, поэтому $HOME
в выходных данных развернется ваш домашний каталог, а подстановка команд фактически запустит команду в запущенной оболочке eval
. Выходные данные "$(date >&2)"
создадут один пустой элемент массива и выведут текущую дату на стандартный вывод. Это вызывает беспокойство, если gen_args.sh
данные из какого-либо ненадежного источника, например с другого хоста в сети, получают имена файлов, созданные другими пользователями. Вывод может включать произвольные команды. (Если бы get_args.sh
он был вредоносным, ему не нужно ничего выводить, он мог бы просто запускать вредоносные команды напрямую.)
Альтернативой кавычкам оболочки, которую трудно проанализировать без eval, было бы использование некоторого другого символа в качестве разделителя в выходных данных вашего скрипта. Вам нужно будет выбрать тот, который не нужен в реальных аргументах.
Давайте выберем #
и получим вывод сценария foo bar#*#asdf
. Теперь мы можем использовать раскрытие команды без кавычек, чтобы разделить вывод команды на аргументы.
$ IFS='#' # split on '#' signs
$ set -f # disable globbing
$ args=( $( ./gen_args3.sh ) ) # assign the values to the array
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
Вам нужно будет установить IFS
позже, если вы зависите от разбиения слов в другом месте скрипта ( unset IFS
должно работать, чтобы сделать его по умолчанию), а также использовать, set +f
если вы хотите использовать глобирование позже.
Если вы не используете Bash или другую оболочку с массивами, вы можете использовать позиционные параметры для этого. Замените args=( $(...) )
на set -- $(./gen_args.sh)
и используйте "$@"
вместо "${args[@]}"
этого. (Здесь тоже нужны кавычки "$@"
, в противном случае позиционные параметры могут быть разбиты на слова.)
eval
их можно использовать, но обычно это не рекомендуется.xargs
это то, что нужно учитывать