Запускать программы в фоновом режиме и перенаправлять их результаты в файл в режиме реального времени.

Я хочу запускать несколько скриптов python одновременно в одном сеансе bash и проверять их выходы соответственно в режиме реального времени. Для выполнения этой задачи я написал простой bash script, который показан ниже:

#!/bin/bash
python 1.py > 1.output &
python 2.py > 2.output &
python 3.py > 3.output &

Когда я использую команду cat 1.output для проверки того, что было напечатано в середине выполнения, однако, ничего не видно.

Подумав некоторое время, я понимаю, что 1.output должен быть заполнен, когда 1.py завершает выполнение. Другими словами, метод, который я использовал здесь, не является способом real time.

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

Кроме того, вы можете предложить мне изменить скрипты python для печати сообщения напрямую, а не stdout. Извините, скрипты здесь слишком сложны для модификации, в них есть патроны print.

что я могу сделать сейчас?

Ответ 1

Переключатель -u и эквивалентная переменная среды PYTHONUNBUFFERED заставляют stdout быть небуферизованными. Попробуйте следующее:

#!/bin/bash
python -u 1.py > 1.output &
python -u 2.py > 2.output &
python -u 3.py > 3.output &

или

#!/bin/bash
export PYTHONUNBUFFERED=yes
python 1.py > 1.output &
python 2.py > 2.output &
python 3.py > 3.output &

Обратите внимание, что -u имеет побочные эффекты: прочитайте документ, чтобы узнать больше.

Ссылка:

Ответ 2

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

Ответ 3

Вы можете попробовать переопределить stderr/stdout в своих сценариях, выполнив следующие действия:

# in the beginning of your script
import os
import sys

desired_output_file = open('/path/to/file', 'a')
os.dup2(desired_output_file.fileno(), sys.stdout)
os.dup2(desired_output_file.fileno(), sys.stderr)

Затем все вызовы print будут записываться в этот специальный файл, а не в стандартный вывод. Однако основная проблема может заключаться в буферизации ввода-вывода. Вы должны каким-то образом flush сохранить содержимое такого файла на диск.