Есть ли способ отправить отображаемую информацию, запустив сценарий bash с параметром -x, в файл, не изменяя при этом стандартный вывод, который видит пользователь, запускающий сценарий?
Это функция отладки, которую я хотел бы реализовать в часто используемом сценарии bash.
Очень признателен.
Вывод из -x идет в stderr, а не в stdout. Но даже это может быть проблемой - многие скрипты будут иметь функциональную зависимость от содержимого stderr, и в некоторых случаях из-за того, что потоки debug и stderr смешиваются вместе, это довольно беспорядочно.
Версии Bash> 4.1 предлагают другое решение: переменная среды BASH_XTRACEFD позволяет указать дескриптор файла, который будет использоваться для отправки потока отладки. Это может быть файл, конвейер или любой другой unix-y добро, которое вам нравится.
# 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 и чередовать их с выходными данными отладки, чтобы ваш журнал был более полным. Подробнее об этом см. https://stackoverflow.com/questions/3173131/redirect-copy-of-stdout-to-log-file-from-within-bash-script-itself.
Большим преимуществом этого подхода перед альтернативами является то, что вы не рискуете изменить поведение вашего скрипта, вставляя отладочные данные в stdout или stderr.
set -x
ничего не отправляет на стандартный вывод, так что здесь нет никаких проблем. Что это делает do - это запись в стандартную ошибку, которая по умолчанию выводится на консоль.
Что вы хотите сделать, так это перенаправить stdout в другой файл, например:
/bin/sh -x /my/script/file 2>/my/log/file
Постановка задачи:
Отобразите вывод скрипта на экране и перенаправьте вывод в файл.
Разрешение:
Использование:
exec &> >(tee logfile)
Tee: tee - это команда bash, которая перенаправляет вывод в файл, а также отображает его на экране.
set -x: если вы не хотите записывать команды сценария в файл журнала (кроме вывода команды), вы можете удалить set -X из сценария ниже.
#!/bin/bash
exec &> >(tee logfile)
set -x
#start your script, I am giving this as an example
cd /home
ls
cd /var/
ls
set +x
Видеть man tee
.
Вы запускаете это как tee commandname filename
и он отобразит вывод команд в stdout
и запишите это также в filename
.