bash: установить -x логов в файл

18

У меня есть сценарий оболочки, set -xчтобы иметь подробный / отладочный вывод:

#!/bin/bash

set -x
command1
command2
...

Вывод выглядит так:

+ command1
whatever output from command1
+ command2
whatever output from command2

Моя проблема, выход оболочки (вызванный set -x) идет в поток ошибок, смешанного с выходом команд ( command1, command2, ...). Я был бы рад иметь на экране «нормальный» вывод (например, скрипт без запуска set -x) и «дополнительный» вывод bash отдельно в файле.

Так что я хотел бы иметь это на экране:

whatever output from command1
whatever output from command2

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

+ command1
+ command2

(также хорошо, если в файле журнала есть все вместе)

set -x 2> fileЯвно doens't принять правильное действие, потому что это не выход из команды набора, но изменить поведение Баша.

Использование bash 2> fileдля всего сценария также не дает правильных результатов, потому что оно перенаправляет stderr каждой команды, которая также выполняется в этой оболочке, поэтому я не вижу сообщения об ошибках команд.

redseven
источник
2
Мой гугл-фу кажется сильным сегодня утром: отправка вывода bash -x в лог-файл без прерывания стандартного вывода
steeldriver

Ответы:

20

Основываясь на этом ответе ServerFault Отправка вывода bash -x в файл журнала без прерывания стандартного вывода , современные версии bash включают BASH_XTRACEFDспециально для указания альтернативного дескриптора файла для выводаset -x

Так, например, вы можете сделать

#!/bin/bash

exec 19>logfile
BASH_XTRACEFD=19

set -x
command1
command2
...

отправить выходные данные set -xв файл logfile, сохраняя при этом стандартные стандартные выходные данные и стандартные потоки ошибок для следующих команд.

Обратите внимание, что использование fd 19 является произвольным - это просто должен быть доступный дескриптор (то есть не 0, 1, 2 или другое число, которое вы уже присвоили).

steeldriver
источник
Он действительно сохраняет журнал трассировки bash отдельно, однако затрудняет чтение двух выходных данных (stdout + stderr на экране и трассировки bash в файлах журналов), поскольку они полностью не синхронизированы. Смотрите решение, которое я только что опубликовал .
Redseven
4

Спустя более года я нашел правильное решение, чтобы и «нормальный» вывод (stdout + stderr - bash trace) на экране и все вместе (stdout + stderr + bash trace) в файле (bash.log) :

exec   > >(tee -ia bash.log)
exec  2> >(tee -ia bash.log >& 2)
exec 19> bash.log

export BASH_XTRACEFD="19"
set -x

command1
command2
redseven
источник
Это просто сочетание ответа стального водителя и этого .
Ярно
3

Steeldriver дал вам один подход. Кроме того, вы можете просто перенаправить STDERR в файл:

script.sh 2> logfile

Это, однако, означает, что и выходные данные, созданные set -xопцией, и любые другие сообщения об ошибках будут отправлены в файл. Решение Steeldriver будет только перенаправлять set -xвывод, что, вероятно, то, что вы хотите.

terdon
источник
«... и результат, созданный параметром set -x, и любые другие сообщения об ошибках, будут отправлены в файл.» И поэтому он не работает для меня. Моя главная проблема заключается в том, что я не вижу «реальных ошибок», потому что весь этот вывод bash идет в stderr. Перенаправление команд сообщений об ошибках также скрыло бы меня от «настоящих ошибок» по-другому.
Redseven
@redseven Боюсь, то, что вы просите, не очень понятно. Не могли бы вы отредактировать свой вопрос и уточнить? Старайтесь избегать использования термина «выходные данные» для всего, что не идет в стандартный вывод. Вы хотите отделить я) нормальный вывод; II) любые ошибки, выданные вашей командой и III) установить -x? Разве не достаточно ответа стального водителя? Если нет, покажите нам простой скрипт, который мы можем скопировать, и скажите, как бы вы хотели, чтобы он вел себя.
тердон
@steeldriver уже отлично ответил на вопрос.
Redseven
@ redseven ах, тогда круто. Поскольку ваш комментарий появился намного позже, я подумал, что вам все еще что-то нужно, и я не мог понять, как ответ SteelDriver не смог решить вашу проблему. Рад, что все это отсортировано.
Terdon