Короткий ответ: используйте двойные кавычки вместо одиночных кавычек (как предложено @Pavel). И когда вы сомневаетесь, используйте set -x
, чтобы узнать, как оболочка анализирует ваши команды.
Длинный ответ: кавычки не передаются команде; вместо этого они разбираются (и удаляются) оболочкой, прежде чем аргументы передаются команде. То, что они делают, - это изменить способ интерпретации оболочки внутри кавычек (как правило, путем подавления особых значений некоторых символов), что означает, что вам нужно выбрать соответствующие кавычки, чтобы разрешить специальные символы, которые вы хотите проанализировать, и подавить их вы должны рассматриваться как простые персонажи. Например, рассмотрим следующую команду:
R CMD BATCH --no-save --no-restore --slave '--args 2 Vocab May12' tabulate.r /dev/tty
оболочка будет игнорировать специальные значения всех символов в одинарных кавычках части команды. Единственными символами с любым особым смыслом являются пробелы, которые обычно действуют как разделители между аргументами; в этом случае одиночные кавычки заставляют оболочку рассматривать их как часть одного аргумента. Эти и другие команды:
R CMD BATCH --no-save --no-restore --slave "--args 2 Vocab May12" tabulate.r /dev/tty
R CMD BATCH --no-save --no-restore --slave --args' '2' 'Vocab' 'May12 tabulate.r /dev/tty
R CMD BATCH --no-save --no-restore --slave --args\ 2\ Vocab\ May12 tabulate.r /dev/tty
... все делают точно то же самое, потому что все они (так или иначе) получить оболочку, чтобы рассматривать пробелы как часть аргумента, а не разделителей между аргументами.
Теперь давайте рассмотрим команду, которая не работает для вас:
R CMD BATCH --no-save --no-restore --slave '--args $1 $2 $3' tabulate.r /dev/tty
Проблема в том, что в то время как одиночные кавычки подавляют особый смысл пространств (как вы хотите), они также подавляет особый смысл $
(который вам не нужен). Поэтому вам нужно что-то более избирательное.Одним из вариантов было бы процитировать/избежать пробелов, но оставить $1
и т.д. неупомянута:
R CMD BATCH --no-save --no-restore --slave --args' '$1' '$2' '$3 tabulate.r /dev/tty
R CMD BATCH --no-save --no-restore --slave --args\ $1\ $2\ $3 tabulate.r /dev/tty
(. Отметить, что обе эти команды делают в точности то же самое) Они будут в основном работать, но есть немного потенциала для проблемы: оболочка заменит $1
и т. д. с аргументами скрипта, но затем он выполняет некоторые дополнительные синтаксические разборки на них: поиск пробелов для использования в качестве разделителей аргументов, подстановочные знаки для сопоставления имен файлов и т. д. Все, что я довольно конечно, вы не хотите, хотя, поскольку аргументы, вероятно, не будут содержать каких-либо специальных символов, это, вероятно, не будет проблемой. Вероятно.
Самый лучший вариант, я вижу, это просто использовать двойные кавычки:
R CMD BATCH --no-save --no-restore --slave "--args $1 $2 $3" tabulate.r /dev/tty
Двойные кавычки подавляющие особый смысл пространств (как вы хотите), позволяют $
вызвать расширение переменных (также, как вы хотите), НО не допускайте дальнейшего разбора после того, как переменные были расширены (также вероятно, что вы хотите). Пробелы или другие забавные символы в аргументах могут по-прежнему вызывать проблемы в сценарии R, но по крайней мере это мешает им создавать проблемы до того, как R-скрипт будет запущен.
Я скептически отношусь к тому, что вам нужны * одиночные кавычки. Когда вы запускаете эту команду из оболочки, оболочка потребляет их и передает одно слово ** без кавычек ** команде R. –
@glennjackman Вам обязательно нужны кавычки. Запуск без кавычек ничего не дает. Я не могу это объяснить, но я попробовал. –
Я согласен с @glenn jackman; вам могут понадобиться кавычки какого-то типа, но точка кавычек заключается в изменении того, как оболочка анализирует его содержимое - они невидимы для самой программы. Например, 'somecmd '--args part1 part2 part3'' запускает somecmd с точно такими же аргументами, что и' somecmd' --args part1 part2 part3 "и' somecmd --args '' part1 '' part2 '' part3'' и 'somecmd --args \ part1 \ part2 \ part3'. Во всех этих случаях кавычки/escape-файлы делают оболочку обрабатывать пространства как часть одного аргумента, а не разделители между аргументами. –