2013-07-25 4 views
0

Как бы вы перешли на перенаправление сценария stdout и stderr в файл, а также отправили stderr скрипта в stdout.Нестандартное перенаправление io

Для иллюстрации:

testscript:

#!/bin/bash 
echo "this goes to stdout" 
echo "this goes to stderr" >&2 

Выполнить testscript таким образом, что она выводит на консоль:

this goes to stderr 

и это идет в лог-файл:

this goes to stdout 
this goes to stderr 

Я чувствую, что сблизился с fifo, но так и не добрался. Для этого нужен tee. Идеи?

ответ

0

Я предполагаю, что это не совсем справедливо для людей, работающих на ответы прямо сейчас, но я думаю, что я получил это:

if [ ! -e /tmp/deployed.err ] 
then 
    mkfifo /tmp/deployed.err 
fi 

tee -a testlog </tmp/deployed.err & 

./testscript 2>/tmp/deployed.err 1>>testlog 

Это, кажется, работает, но я волнуюсь, что сообщения в журнал выйдет из строя. У кого-то есть лучшая идея?

0

Это

command 2>&1 | tee somefile 

будет посылать ОБА потоки вывода на tee так, как собирается в файл и стандартный вывод тоже.

если вы хотите перенаправить stderr и стандартный вывод различные tee, вы можете использовать что-то вроде:

command > >(tee out.log) 2> >(tee err.log >&2) 

и так далее ... (промежутки между > >( являются обязательными)

0

Вы можете попробовать что-то вроде этого

./script 2>&1 1>log | tee -a log 

стандартный вывод будет отправить войти в 1>log и тройник делает задание отправки его на stdout и запись.

PS: Как-то у меня плохое отношение к этому методу. Прошу прокомментировать, если вы так чувствуете.

0

simething simplier. это основано на bashizm внутренней вилки на первый, тестовый скрипт:

#!/bin/bash 
for i in {1..1000}; do 
    echo STDOUT $i>&1 
    echo STDERR $i>&2 
done 

и рядом, перенаправляя сценарий:

(./xxtext.sh 1>>logfile)2>&1|\ #subprocess/fork in brackets with redir stdout to logfile. 
#above, main process redirect stderr to stdout for properly pipe 
while read x; do echo $x; echo $x>>logfile; done #second read sequently stdin 
#redirected from stderr, and both print to the screen and append to logfile. 

К сожалению, это не спасло правильно последовательность, потому что два потока управляются двумя различными процесса с буферизацией труб с ними.

Если вы действительно хотите сохранить последовательность, единственный способ - использовать системный вызов 'select' и читать как stdout, так и stderr из внутреннего скрипта. Я верю, что bash этого не поддерживает. Вы можете сделать это на C или Perl или другом более продвинутом языке. Полезный пример в perl i, найденный по адресу: http://www.perlmonks.org/bare/?node_id=419919 Это вызов команды bc.