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

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

Я запускаю скрипт, который выглядит следующим образом.

#!/bin/bash
dat=$(date +%Y%m%d%H%M)
run_sim xmsclst gemm dcs s xec -post_min -d |& tee logx.$dat

run_sim — это другой скрипт csh, и он вызывает программу make для проведения длительного симуляционного расчета (симуляция включает rtl файлы и модель на уровне вентилей для разработки нашего чипа). Проблема, с которой я столкнулся, заключается в следующем:
Обычно ход симуляции отображается в терминале сразу же, как только модель симуляции что-то печатает, используя системный вызов verilog $display. Но если я использую приведённую выше команду, которая использует pipeline и команду tee, текстовый вывод где-то буферизуется, и я не вижу его на экране сразу, поэтому не могу узнать статус симуляции. Только когда я нажимаю ctrl-C, чтобы остановить симуляцию, тогда на экране появляются буферизованные строки отображения, но тогда я не могу возобновить свою симуляцию, потому что она уже остановлена. Я знаю, что если я не использую pipeline и команду tee, я мог бы видеть вывод по мере прогресса симуляции. Но я уже начал симуляцию, и она длится уже более 2 часов, и у меня нет много времени, чтобы повторить этот процесс симуляции сегодня.
Есть ли какой-либо способ увидеть ход симуляции, не останавливая её? И, надеюсь, не убивая процесс tee? (С учетом этого, я думаю, возможно, я смогу убить только процесс tee, и текст может появляться снова нормально.)

Ответ или решение

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

Решение проблемы буферизации

  1. Использование stdbuf:
    Вы можете использовать команду stdbuf для изменения параметров буферизации ввода/вывода для вашего сценария. Попробуйте изменить ваш скрипт следующим образом:

    #!/bin/bash
    dat=$(date +%Y%m%d%H%M)
    run_sim xmsclst gemm dcs s xec -post_min -d |& stdbuf -o0 tee logx.$dat

    Здесь -o0 отключает буферизацию стандартного вывода, что позволит выводить данные на экран немедленно.

  2. Использование unbuffer:
    Если у вас установлен пакет expect, вы можете использовать unbuffer для достижения аналогичного эффекта:

    #!/bin/bash
    dat=$(date +%Y%m%d%H%M)
    unbuffer run_sim xmsclst gemm dcs s xec -post_min -d |& tee logx.$dat

    unbuffer заставит программу выводить данные в реальном времени.

  3. Попробуйте использовать pv:
    Также вы можете воспользоваться утилитой pv (Pipe Viewer). Это может также помочь с выводом в реальном времени:

    #!/bin/bash
    dat=$(date +%Y%m%d%H%M)
    run_sim xmsclst gemm dcs s xec -post_min -d |& pv -l -s <expected_line_count> | tee logx.$dat

    Вам необходимо заменить <expected_line_count> на ожидаемое количество строк вывода, которое может помочь pv более эффективно управлять выводом.

Альтернативное решение

Если вы уже запустили процесс и не хотите его останавливать, вы можете попытаться использовать команду kill для завершения процесса tee, не останавливая сам процесс run_sim. Вы можете найти PID (идентификатор процесса) для tee с помощью команды:

ps aux | grep tee

После нахождения PID вы можете убить только процесс tee:

kill -SIGTERM <tee_pid>

Это должно вернуть контроль вывода к run_sim, который может начать выводить данные на экран.

Заключение

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

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

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