Вопрос или проблема
Я запускаю скрипт, который выглядит следующим образом.
#!/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
, стандартный вывод может быть буферизирован, что приводит к задержке в отображении информации на экране.
Решение проблемы буферизации
-
Использование
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
отключает буферизацию стандартного вывода, что позволит выводить данные на экран немедленно. -
Использование
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
заставит программу выводить данные в реальном времени. -
Попробуйте использовать
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
, который может начать выводить данные на экран.
Заключение
С помощью указанных выше методов вы можете управлять буферизацией вывода и получать статус вашего симуляционного процесса без его остановки. Создание таких решений может значительно улучшить рабочие процессы при выполнении длительных операций.