2015-09-19 6 views
2

Я пытаюсь написать Баш скрипт, где каждая команда передается через функцию, которая оценивает команду, используя следующую строку:Eval команды с Stderr/STDOUT перепрофилирования вызывая проблемы

eval $1 2>&1 >>~/max.log | tee --append ~/max.log 

Пример для случая, когда это не работает, когда вы пытаетесь оценить команду cd:

eval cd /usr/local/src 2>&1 >>~/max.log | tee --append ~/max.log 

Часть причины, по которой проблема является | tee --append ~/max.log. Любая идея, почему я испытываю проблемы?

+0

Что не работает? Он не записывается в каталог? – edi9999

+0

cd не работает с трубами, 'папка cd | Например, ls' не поместит вас в «папку» – edi9999

+0

Можете ли вы перевести функцию main на функцию и использовать 'tee' для выхода функции? Что-то вроде 'function mymain {...}' и 'mymain 2> & 1 | tee -append ~/max.log'? Или использовать что-то вроде 'script'? –

ответ

4

На странице bash(1) людей:

Каждая команда в конвейере выполняется как отдельный процесс (то есть, в субоболочке).

Поэтому cdне может изменить рабочий каталог текущей оболочки при использовании в трубопроводе. Чтобы обойти это ограничение, обычный подход будет заключаться в группу cd с другими командами и перенаправить вывод команды группы:

{ 
    cd /usr/local/src 
    command1 
    command2 
} | tee --append ~/max.log 

Не нарушая существующий дизайн, вы могли бы вместо того, чтобы справиться с cd специально в функции фильтра:

# eval all commands (will catch any cd output, but will not change directory): 
eval $1 2>&1 >>~/max.log | tee --append ~/max.log 
# if command starts with "cd ", execute it once more, but in the current shell: 
[[ "$1" == cd\ * ]] && $1 

в зависимости от ситуации, это может быть не достаточно: Вы, возможно, придется обрабатывать другие команды, которые изменяют среды или оболочки переменные, как set, history, ulimit, read , pushd, и popd также. В этом случае, вероятно, было бы хорошей идеей переосмыслить дизайн программы.

+0

+1 за причину. Также необходимо использовать специальный случай, который устанавливает или объявляет переменную envvar или shell, если эти параметры используются. Включая 'read' и т. Д. И' set' из '$ *' и/или параметров оболочки. Или изменяет настройки «ulimit». Или 'история'. И, возможно, больше я пропустил. Легче перенаправить правильно. –

+0

@ dave_thompson_085: Спасибо, я сделал общий оператор более общим, чтобы включить все, что изменяет переменные среды или оболочки. –

 Смежные вопросы

  • Нет связанных вопросов^_^