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