Надішліть bash -x вихід у logfile, не перебиваючи стандартний вихід


12

Чи є спосіб надіслати інформацію, що відображається, запустивши скрипт bash з опцією -x у файл, не змінюючи при цьому стандартного виводу, який бачить користувач, що виконує сценарій?

Це функція налагодження, яку я хотів би реалізувати в bash-скрипті, який ми часто використовуємо.

Цінується.

Відповіді:


21

Вихід з -x йде на stderr, а не stdout. Але навіть це може бути проблемою - велика кількість скриптів матиме функціональну залежність від вмісту stderr та його різновиду безладдя, щоб потоки налагодження та stderr змішувалися разом у деяких випадках.

Версії Bash> 4.1 пропонують інше рішення: змінна середовище BASH_XTRACEFD дозволяє вказати дескриптор файлу, який буде використовуватися для надсилання потоку налагодження. Це може бути файл або труба або будь-яке інше добро, яке вам подобається.

# Use FD 19 to capture the debug stream caused by "set -x":
exec 19>/tmp/my-script.log
# Tell bash about it  (there's nothing special about 19, its arbitrary)
export BASH_XTRACEFD=19

# turn on the debug stream:
set -x

# run some commands:
cd /etc
find 
echo "Well, that was fun."

# Close the output:
set +x
exec 19>&-

# See what we got:
cat /tmp/my-script.log

З трохи більше химерності ви можете робити інші речі - наприклад, робити «трійник» на потоках stdout та / або stdin та переплутати ті, хто має вихід налагодження, щоб ваш журнал був більш повним. Детальніше про це дивіться на веб-сторінці /programming/3173131/redirect-copy-of-stdout-to-log-file-from-within-bash-script-itself .

Велика перевага цього підходу перед альтернативами полягає в тому, що ви не ризикуєте змінити поведінку свого сценарію, вводячи вихідний налагодження в stdout або stderr.


Дивіться також тут, як знайти невикористаний дескриптор файлу для цього файлу.
jarno

Чи потрібно закрити дескриптор файлу (тобто рядок exec 19>&-)? На мій досвід, він закривається автоматично, коли сценарій закінчується.
jarno

1
Код, показаний вище, не передбачає, що ви запускаєте скрипт, або тривалість сценарію і т. Д. Це правда, що якщо ви просто зробите те, що робить цей фрагмент, і вкладете його в сценарій, обробка файлу буде бути закритим лише тому, що вся оболонка минає в кінці сценарію. Тож у такому разі не потрібно суворо закривати ручку. Але в цілому при кодуванні ресурсу є хорошою практикою закривати те, що ви відкрили, оскільки тоді ваш код можна використовувати в більш широкому контексті, коли ведення господарства має більше значення.
Stabledog

Чому ви експортуєте BASH_XTRACEFD? Чому б просто не встановити для цього значення?
jarno

У будь-якому випадку, альтернативним способом закрити дескриптор файлу є встановлення нового значення (наприклад, null) для BASH_XTRACEFD або його зняття.
jarno

4

set -xне надсилає нічого на стандартний вихід, тому немає жодної проблеми. Що він робить - це записати до стандартної помилки, яка за замовчуванням переходить до консолі.

Що ви хочете зробити, це перенаправити stdout на інший файл, наприклад такий:

/bin/sh -x /my/script/file 2>/my/log/file

1

Див man tee.

Ви запускаєте його як, tee commandname filenameі він відображатиме команди, які виводять stdoutі записують їх також filename.

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