Вопрос или проблема
Я знаю, что могу перенаправить вывод xtrace
в some_file
следующим образом:
exec 2>> some_file
set +x
…но это отправляет в some_file
не только вывод xtrace
, но и любое другое содержимое, которое отправлено изначально в fd 2
, включая большинство сообщений об ошибках и предупреждений, не связанных с xtrace
.
Есть ли способ захватить только вывод xtrace
в some_file
?
Я должен добавить, что ищу способ сделать это с минимальными искажениями самого вывода xtrace
и собранной информации о времени с помощью настройки PS4
, например:
zmodload zsh/datetime
export PS4='${(j::)epochtime} %N:%i> '
Это может быть не тем решением, которое вы ищете, но, столкнувшись с аналогичной ситуацией в прошлом, я обычно пишу парсер на Python, чтобы взять файл трассировки и выводить только данные, которые меня интересуют, в результирующий файл. Пока шаблоны «ненужного текста», который вас не интересует, предсказуемы/различимы от вывода xtrace, разбор должен быть чрезвычайно простым.
Пример — захват трассировки всех ввода-вывода по всем очередям отправки для 20-минутного теста, состоящего из чтений и записей, приводит к созданию файла размером 40-70 ГБ, но после разборки данных, которые меня интересовали, мой результирующий файл составляет всего ~1-3 ГБ и фактически пригоден для анализа и визуализации. Конечно, с такими большими размерами файлов, обработка на серверной системе занимает ~15-30 минут, но выполняя тот же процесс (другой сценарий, та же идея — несколько журналов, каждый размером всего около 24 кб) — я могу получить все данные из всех журналов в одном удобном для использования файле менее чем за 2 секунды.
Все это к тому, что может быть полезно добавить шаг постобработки, который может добавить несколько секунд/минут к общей захвату, вместо ожидания одного решения для всех проблем.
Желаю удачи!
Если я правильно вас понимаю, у вас следующая ситуация:
xtrace some_command
… и вы хотите, чтобы вывод xtrace
записывался в какой-то файл, а вывод some_command
отправлялся на консоль.
Возможно, это не лучшее решение, но (используя Linux) я бы сделал это следующим образом:
xtrace sh my_script.sh > xtrace_output.txt
… и файл my_script.sh
выглядит так:
#!/bin/sh
some_command > /dev/tty
К сожалению, я не уверен, есть ли /dev/tty
в других Unix-системах, кроме Linux.
ИЗМЕНЕНИЕ
Вы можете сделать это даже без файла:
xtrace bash -c 'some_command > /dev/tty' > xtrace_output.txt
Ответ или решение
Чтобы захватить вывод xtrace
в отдельный файл, минуя перенаправление всех возможных ошибок и предупреждений, можно воспользоваться несколькими стратегиями, оптимальными для вашего контекста. Вопрос заключается в том, как выделить только вывод отладочного режима xtrace
в файл без смешивания с другими типами вывода, такими как стандартные ошибки.
Проблема
Когда мы перенаправляем стандартный поток ошибок (fd 2) в файл, это включает в себя как отладочные сообщения, генерируемые xtrace
, так и любые другие ошибки, что недопустимо в специфических сценариях, где требуется только чистый вывод отладки.
Решение
Использование разделения потоков
-
Создание временного файла для
xtrace
:Вы можете создать именованный канал (
FIFO
), чтобы разделить потоки. Это позволит захватить только выводxtrace
в файл, оставляя стандартные ошибки видимыми в консоли:mkfifo /tmp/xtrace_fifo tee xtrace_output.txt < /tmp/xtrace_fifo & exec 3>/tmp/xtrace_fifo PS4='+$(date "+%s.%N")\011 ' BASH_XTRACEFD=3 set -x # Ваши команды здесь set +x exec 3>&- rm /tmp/xtrace_fifo
В этом примере создается именованный канал
/tmp/xtrace_fifo
, через который отладочные данные направляются в файлxtrace_output.txt
. Это решает проблему смешивания различных типов вывода. -
Использование модуля
zsh/datetime
для временной метки:Если вы используете
zsh
и хотите включить временные метки в ваш вывод xtrace, модульzsh/datetime
уже предоставляет функционал для получения подробной временной информации. Настройка переменнойPS4
с использованиемepochtime
помогает получить метки времени в нужном формате, например:zmodload zsh/datetime export PS4='${(j::)epochtime} %N:%i> '
Разделение отладочного и стандартного вывода
Помимо использования именованных каналов, можно воспользоваться пост-обработкой как альтернативным методом. Это включает запись всего вывода в файл и последующую фильтрацию, например, с использованием Python для удаления ненужных данных.
Преимущества предложенного метода
- Чистота вывода: Разделяя потоки, вы получаете только нужную информацию в заданном файле.
- Гибкость: Метод подходит для разных сценариев и может быть адаптирован для других оболочек и конфигураций.
- Оптимизация временных затрат: Предложенный подход минимизирует искажения данных и сохраняет последовательность вывода во времени.
Заключение
Это решение позволяет эффективно собирать данные отладки в файл, сохраняя при этом раздельные потоки вывода и ошибок. Используйте предложенные стратегии, чтобы обеспечить ясность и полноту данных отладки в вашем процессе, улучшая тем самым качество отладки скриптов.
Если у вас возникли дополнительные вопросы или нужны рекомендации по конкретным сценариям, не стесняйтесь обращаться. Удачи в вашей работе!