Обновление: этот ответ основан на SGE qsub
, а не на TORQUE qsub
, поэтому интерфейс командной строки несколько отличается. В частности, TORQUE qub
, похоже, не поддерживает прямую передачу аргументов, поэтому второй подход не работает.
В основном это проблема правильного цитирования и имеет мало общего с самой отправкой движка сетки. Если вы просто хотите исправить текущий скрипт, вам следует использовать eval "${CMD}"
, а не ${CMD}
. Вот подробный анализ того, что происходит, когда вы делаете ${CMD}
в одиночку (в анализе мы предполагаем, что в path
нет ничего смешного):
Ваша командная строка qsub
обрабатывается, и кавычки удаляются, поэтому переданная переменная среды ARGS
равна data_directory "wonderful graph title"
.
Вы сделали CMD="/path/make_graph $ARGS"
, поэтому значение CMD
равно /path/make_graph data_directory "wonderful graph title"
(я представляю строковый литерал без кавычек, то есть значение буквально содержит символы кавычек).
Вы сделали ${CMD}
. Bash выполняет расширение параметра для этого, что составляет:
- Expanding
${CMD}
to its value /path/make_graph data_directory "wonderful graph title"
;
- Поскольку
${CMD}
не заключено в кавычки, выполните разбиение слов, чтобы в итоге в командной строке было пять слов: /path/make_graph
, data_directory
, "wonderful
, graph
, title"
. Последние четыре рассматриваются как аргументы вашего make_graph
, что, безусловно, не то, что вам нужно.
С другой стороны, если вы используете eval "${CMD}"
, это как если бы вы набрали /path/make_graph data_directory "wonderful graph title"
в интерактивной оболочке, что является желаемым поведением.
Вы должны прочитать больше о eval
, расширении параметров и т. д. в Справочном руководстве по Bash а>.
Исправленный скрипт:
#!/usr/bin/env bash
[[ -z ${ARGS+xxx} ]] && { echo "NO ARGS SPECIFIED!" >&2; exit 1; }
CMD="/path/make_graph ${ARGS}"
echo "CMD: ${CMD}"
echo "Job started on $(hostname) at $(date)" # backticks are deprecated
eval "${CMD}"
Кстати, чтобы проверить это, вам не нужно отправлять это в механизм сетки; просто сделать
ARGS="data_directory \"wonderful graph title\"" bash make_graph.pbs
Хорошо, я просто указал, что не так, и исправил это. Но действительно ли это «правильный способ» передавать аргументы заданиям grid engine? Нет, я так не думаю. Аргументы есть аргументы, и их не следует путать с переменными среды. qsub
позволяет вам передавать аргументы напрямую (qsub
синопсис: qsub [ options ] [ command | -- [ command_args ]]
), так зачем кодировать их в env var и в конечном итоге беспокоиться о заключении в кавычки?
Вот лучший способ написать сценарий отправки:
#!/usr/bin/env bash
[[ $# == 0 ]] && { echo "NO ARGS SPECIFIED!" >&2; exit 1; }
CMD="/path/make_graph $@"
echo "CMD: ${CMD}"
echo "Job started on $(hostname) at $(date)" # backticks are deprecated
/path/make_graph "$@"
Здесь "$@"
эквивалентно "$1" "$2" ...
— все аргументы точно передаются как есть (см. соответствующий раздел в справочном руководстве по Bash).
Одна вещь, к сожалению, в этом, однако, заключается в том, что, хотя команда выполняется правильно, напечатанная может быть неправильно процитирована. Например, если вы делаете
qsub make_graph.pbs data_directory "wonderful graph title"
тогда выполняется make_graph.pbs data_directory "wonderful graph title"
, но напечатанное CMD
равно make_graph.pbs data_directory wonderful graph title
. И, насколько я знаю, нет простого способа исправить это, поскольку кавычки всегда удаляются из аргументов, независимо от того, как выполняется разбиение на слова. Если напечатанная команда действительно важна для вас, есть два решения:
Используйте специальный «экран-экран» (довольно легко написать его для себя), чтобы процитировать аргументы перед печатью;
Используйте другой язык сценариев, где кавычки оболочки легко доступны, например, Python (shlex.quote
) или Ruby (Shellwords.shellescape
).
person
4ae1e1
schedule
21.03.2015