2013-12-16 2 views
4

Недавно я обнаружил неожиданное поведение в сценарии bash, и я хотел бы это понять, прежде чем я его обойду. Вот упрощенный пример:Перенаправление сценариев Bash не работает, почему?

#! /bin/sh 
SCRIPT="/tmp/echoscript.sh >> /tmp/log" 
/bin/sh ${SCRIPT} 

echoscript.sh просто делает «эхо„ABC“»

Неожиданным дело в том, что «а» идут к терминалу, а не к/файлу TMP/журнала. Почему это?

Если я меняю третью линию:

/bin/sh ${SCRIPT} >> /tmp/log 

Тогда я получить ожидаемый результат; 'abc' переходит в файл журнала.

ответ

3

Вы не можете переназначить такие переменные. Когда вы делаете Bash интерпретирует /bin/sh ${SCRIPT}, как если бы Вы писали:

/bin/sh "/tmp/echoscript.sh" ">>" "/tmp/log" 

Обратите внимание, как ">>" котируется, убивая предпринятое переназначение. Это происходит из-за того, что Bash анализирует команду поэтапно, и разбор перераспределения происходит до расширения переменной. Значения переменных не проверяются для перенаправления.

4

Когда переменные расширены, единственной последующей обработкой результата является разбиение слов и расширение подстановочных знаков (например, подглаживание). Результат не сканируется для других специальных операторов, таких как перенаправление.

Если вы хотите полную переработку командной строки, вы должны использовать eval:

eval "/bin/sh ${SCRIPT}" 
1

Это не будет делать то, что вы ожидаете, поскольку редирект не обрабатывается в $ {SCRIPT}. Вы получите /bin/sh: /tmp/echoscript.sh >> /tmp/log: No such file or directory.

Вам необходимо сообщить оболочке оценить $ {SCRIPT} перед запуском, как это:

eval /bin/sh ${SCRIPT} 
$ cat /tmp/log 
abc 
1

еще один способ:

alias SCRIPT="/bin/sh /tmp/echoscript.sh >> /tmp/log" 
SCRIPT 
Смежные вопросы