Я написав сценарій, який може створити ці аргументи для мене з цитатами
Якщо висновок правильно цитується для оболонки, і ви довіряєте виводу , тоді ви можете запустити 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)"
створили б один порожній елемент масиву та надрукували поточну дату в stdout. Це викликає занепокоєння, якщо 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
є що також врахувати