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 кожної команди, яка також виконується в цій оболонці, тому я не бачу повідомлення про помилки команд.


2
Мій google-fu, здається, сильний сьогодні вранці: надішліть bash -x вихід у logfile, не
перебиваючи

Відповіді:


20

Виходячи з цього відповіді ServerFault Відправити bash -x вихід у logfile, не перебиваючи стандартний вихід , сучасні версії 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 або іншим числом, яке ви вже призначили).


Він дійсно зберігає журнал слідів bash окремо, проте дуже важко читати 2 виходи (stdout + stderr на екрані та bash слід у файлах журналу), оскільки вони повністю не синхронізовані. Дивіться рішення, що я щойно опублікував .
redseven

4

Після більш ніж року я знайшов правильне рішення мати як "нормальний" вихід (stdout + stderr - баш слід), так і всі разом (stdout + stderr + bash слід) у файлі (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

Це лише поєднання відповіді steeldriver і цього .
jarno

3

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

script.sh 2> logfile

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


"... і вихід, створений параметром set -x, і будь-які інші повідомлення про помилки, перейдуть у файл." І тому для мене це не працює. Моє головне питання - я не легко бачу "справжні помилки", тому що весь цей баш-вихід виходить на stderr. Перенаправлення повідомлень про помилки команд також приховало б мене "справжні помилки" по-іншому.
redseven

@redseven Боюся, те, про що ви просите, не дуже зрозуміло. Чи можете ви відредагувати своє запитання та уточнити? Спробуйте уникати використання терміна "вихід" для всього, що не збирається виводити. Ви хочете відокремити i) нормальний вихід; ii) будь-які помилки, передані вашою командою, і iii) встановити -x? Чи недостатньо відповіді Steeldriver? Якщо ні, покажіть нам простий сценарій, який ми можемо скопіювати, і скажіть нам, як ви хочете, щоб він поводився.
тердон,

@steeldriver вже чудово відповів на питання.
redseven

@redseven ах, круто тоді. Оскільки ваш коментар з’явився набагато пізніше, я подумав, що вам все-таки потрібно щось, і я не міг зрозуміти, як відповідь steeldriver не змогла вирішити вашу проблему. Радий, що тоді все відсортовано.
тердон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.