Как сохранить вывод xtrace (только его) в файл?

Вопрос или проблема

Я знаю, что могу перенаправить вывод 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, так и любые другие ошибки, что недопустимо в специфических сценариях, где требуется только чистый вывод отладки.

Решение

Использование разделения потоков

  1. Создание временного файла для 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. Это решает проблему смешивания различных типов вывода.

  2. Использование модуля zsh/datetime для временной метки:

    Если вы используете zsh и хотите включить временные метки в ваш вывод xtrace, модуль zsh/datetime уже предоставляет функционал для получения подробной временной информации. Настройка переменной PS4 с использованием epochtime помогает получить метки времени в нужном формате, например:

    zmodload zsh/datetime
    export PS4='${(j::)epochtime} %N:%i> '

Разделение отладочного и стандартного вывода

Помимо использования именованных каналов, можно воспользоваться пост-обработкой как альтернативным методом. Это включает запись всего вывода в файл и последующую фильтрацию, например, с использованием Python для удаления ненужных данных.

Преимущества предложенного метода

  • Чистота вывода: Разделяя потоки, вы получаете только нужную информацию в заданном файле.
  • Гибкость: Метод подходит для разных сценариев и может быть адаптирован для других оболочек и конфигураций.
  • Оптимизация временных затрат: Предложенный подход минимизирует искажения данных и сохраняет последовательность вывода во времени.

Заключение

Это решение позволяет эффективно собирать данные отладки в файл, сохраняя при этом раздельные потоки вывода и ошибок. Используйте предложенные стратегии, чтобы обеспечить ясность и полноту данных отладки в вашем процессе, улучшая тем самым качество отладки скриптов.

Если у вас возникли дополнительные вопросы или нужны рекомендации по конкретным сценариям, не стесняйтесь обращаться. Удачи в вашей работе!

Оцените материал
Добавить комментарий

Капча загружается...