Как зарегистрировать вывод сценария оболочки в сценарии

У меня есть скрипт ksh93 (но вопрос не связан с ksh).

В настоящее время я запускаю свой скрипт примерно так:

./script 2>&1 | tee logfile

Мне интересно, что я должен был иметь в своем сценарии, чтобы получить точно такой же результат (вывод экрана и файл журнала, содержащий вывод как STDOUT, так и STDERR). Конечно, я хочу избежать добавления '| tee logfile' для каждого эхо/печати, которое я делаю.

Конечно, способ сделать это может состоять в том, чтобы обернуть мой сценарий в другой, который просто запускает './script 2>&1 | tee logfile», но мне было интересно, можно ли это сделать внутри самого скрипта.


person claf    schedule 09.10.2013    source источник


Ответы (3)


Один общий метод, который несколько хрупкий:

#!/bin/sh
test -z "$NOEXEC" && { NOEXEC=1 exec "$0" "$@" 2>&1 | tee logfile; exit; }
...

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

person William Pursell    schedule 09.10.2013
comment
Не могли бы вы прокомментировать необходимость exit? Кажется, что это заставит скрипт всегда выходить со статусом 0, независимо от статуса выхода tee. - person chepner; 09.10.2013
comment
Неважно, exit нужен, чтобы скрипт не запускался дважды. Но, возможно, exit $? необходимо. - person chepner; 09.10.2013
comment
exit без аргументов совпадает с exit $? - person William Pursell; 09.10.2013
comment
вздох Моя ошибка; Я думал, что он по умолчанию равен 0. - person chepner; 09.10.2013

Если текущее содержимое вашего скрипта:

command1 arg1
command2 arg2

Вы можете обернуть этот лот (внутри скрипта) следующим образом:

{
command1 arg1
command2 arg2
} 2>&1 | tee logfile

Код с { на } теперь является единицей перенаправления ввода/вывода в скрипте; перенаправление ввода-вывода в конце применяется ко всем вложенным командам. Он не создает подоболочку; любые переменные, установленные в командах, доступны сценарию после перенаправления ввода-вывода.

{ и } синтаксически немного своеобразны; в частности, перед } должна стоять точка с запятой или новая строка.

person Jonathan Leffler    schedule 09.10.2013
comment
ваше решение кажется более чистым, чем решение Уильяма, но при использовании с моим скриптом оно возвращается, не выполняя всю работу. странно, не знаю почему, и пока нет времени на расследование. У меня есть много команд, запускаемых через ssh на удаленных машинах, которые не выполняются в скобках (используя ksh93). - person claf; 10.10.2013
comment
Странно — я не уверен, почему это произошло. - person Jonathan Leffler; 10.10.2013

Просто поместите свой код в функцию и вызовите ее.

your_func(){
#your code
}
your_func $@ 2>&1 | tee logfile
person technosaurus    schedule 09.10.2013