У меня есть сценарий удара с большим выводом, и я хотел бы измениться, тот сценарий (не создают новый) скопировать весь вывод в файл, точно так же, как это произошло бы, если бы я передавал его по каналу через мишень.
У меня есть файл script.sh:
#!/bin/bash
init
do_something_that_outputs_stuff_to_STDOUT
launch_applications_that_output_to_STDOUT
fini
и я хотел бы сделать копию STDOUT в файл script.log, не имея необходимость вводить ./script.sh | tee script.log
каждый раз.
Спасибо, Tom
Я не мог заставить очень простую остроту Dennis работать, таким образом, вот намного более замысловатый метод. Я попробовал бы его первое.
Как упомянуто, можно использовать должностное лицо для перенаправления стандартной погрешности и стандарта для всего сценария. Как так:
exec > $LOGFILE 2>&1
Это произведет весь stderr и stdout к $LOGFILE.
Теперь, так как Вы хотите отобразить это к консоли, а также файлу журнала, Вы также оказываетесь перед необходимостью использовать именованный канал для должностного лица для записи в, и мишень для чтения из.
(Острота Dennis технически делает это также, хотя, очевидно, по-другому) сам канал создается с mkfifo $PIPEFILE
. Затем сделайте следующее.
# Start tee writing to a logfile, but pulling its input from our named pipe. tee $LOGFILE < $PIPEFILE & # capture tee's process ID for the wait command. TEEPID=$! # redirect the rest of the stderr and stdout to our named pipe. exec > $PIPEFILE 2>&1 echo "Make your commands here" echo "All their standard out will get teed." echo "So will their standard error" >&2 # close the stderr and stdout file descriptors. exec 1>&- 2>&- # Wait for tee to finish since now that other end of the pipe has closed. wait $TEEPID
Если Вы хотите быть полными, можно создать и уничтожить файл именованного канала в запуске и конце сценария.
Для записи я подобрал большую часть из этого от очень информативного сообщения в блоге случайного парня: (Заархивированная версия)
Просто добавьте это к началу Вашего сценария:
exec > >(tee -ia script.log)
Это добавит весь вывод, отправленный в stdout в файл script.log
, отъезд предыдущего содержания на месте. Если Вы хотите запуститься новый каждый раз, когда скрипт запущен, просто добавляют rm script.log
прямо перед этим exec
управляйте или удалите -a
от tee
команда.
-i
причины опции tee
проигнорировать сигналы прерывания и может позволить tee
поймать более полный выходной набор.
Добавьте эту строку, чтобы также зафиксировать все ошибки (в отдельном файле):
exec 2> >(tee -ia scripterr.out)
Пробелы между несколькими >
символы важны.
Если Вы хотите копию вывода, можно использовать tee
сюда:
#!/bin/bash
init
do_something_that_outputs_stuff_to_STDOUT | tee script.log
launch_applications_that_output_to_STDOUT | tee -a script.log
fini
Это только зарегистрирует stdout к script.log как бы то ни было. Если Вы хотите удостовериться и stderr и stdout перенаправляются, используют:
#!/bin/bash
init
do_something_that_outputs_stuff_to_STDOUT 2>&1 | tee script.log
launch_applications_that_output_to_STDOUT 2>&1 | tee -a script.log
fini
Вы могли даже сделать это немного более любезным с небольшой функцией:
#!/bin/bash
LOGFILE="script.log"
# Wipe LOGFILE if you don't want to add to it at each run
rm -f "$LOGFILE"
function logcmd() {
local cmd="$1" logfile=${LOGFILE:-script.log} # Use default value if unset earlier
# Launch command, redirect stderr to stdout and append to $logfile
eval '$cmd' 2>&1 | tee -a "$logfile"
}
init
logcmd "do_something_that_outputs_stuff_to_STDOUT"
logcmd "launch_applications_that_output_to_STDOUT"
fini
#!/bin/bash
init
do_something_that_outputs_stuff_to_STDOUT > script.log 2>&1
launch_applications_that_output_to_STDOUT >> script.log 2>&1
fini
Вы видите больше о том, как это работает здесь: http://www.xaprb.com/blog/2006/06/06/what-does-devnull-21-mean/
Это - объединенная версия ответа, отправленного Dennis Williamson ранее. Добавляет оба допускают ошибку и станд. к script.log в правильном порядке.
Добавьте эту строку к началу Вашего сценария:
exec > >(tee -a script.log) 2>&1
Отметьте пространство между >
знаки. Работы для меня на ударе GNU, версии 3.2.25 (1) - выпуск (x86_64-redhat-linux-gnu)
Я предполагаю, что другой подход - что-то вроде этого:
#!/bin/bash
# start grouping at the top
{
# your script goes here
do_something_that_outputs_stuff_to_STDOUT
launch_applications_that_output_to_STDOUT
# and at the bottom, redirect everything from the grouped commands
} 2>&1 | tee script.log