Получение выходного файла FILE из процесса Python Popen? - PullRequest
0 голосов
/ 06 апреля 2011

Я написал программу на Python для взаимодействия с скомпилированной программой (назовите ее ProgramX), у которой есть некоторые особенности, с которыми трудно справиться.Мне нужно передать многие тысячи входных файлов в ProgramX через мою программу на Python.Я хотел бы получить выходной файл, который ProgramX создает при каждом запуске, и переименовать его в нечто разумное, например, inputfilename.output.

Проблема возникает в выходном файле, который написан ProgramX - он называется непредсказуемым методом, который записывает и «беспощадно перезаписывает» выходной файл, если он уже существует (что имеет местобольшую часть времени).Скорее всего, это связано с тем, что к выходным файлам есть стандартный префикс: подумайте ProgramX.notQuiteRandomNumber.

Единственное, о чем я могу подумать, так это сделать в моей оболочке bash:

PROGRAMXOUTPUT=$(ls -ltr ProgramX* | tail -n -1 | awk '{print $8}')
mv $PROGRAMXOUTPUT input.output

Что делает 90% от того, что мне нужно, но прежде чем я запрограммирую весь этот удар в серию утверждений Попена, есть ли лучший способ сделать это?Эта проблема кажется чем-то, что люди могут иметь гораздо лучшее решение, чем я думаю.

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

Бонус: я планировал запустить несколько экземпляров программы в одном каталоге, поэтому мой наивный подход, приведенный выше, может начать вызывать непредвиденные проблемы.Так что, возможно, что-то необычное, которое следит за PID ProgramX и отслеживает его вывод.

Ответы [ 3 ]

2 голосов
/ 06 апреля 2011

Чтобы сделать то, что делает вышеописанный скрипт оболочки, при условии, что у вас есть только один ProgramX* в текущем каталоге:

import glob, os

programxoutput = glob.glob('ProgramX*')[0]
os.rename(programxoutput, 'input.output')

Если вам нужно отсортировать по времени и т. Д., Есть и способы сделать это (см. os.stat), но использование самой последней даты модификации - это рецепт для неприятных условий гонки, если вы будете бегать несколько раз. копии ProgramX одновременно.

Я бы предложил вместо этого создавать и переходить на новый, возможно, временный каталог для каждого прогона ProgramX, чтобы у прогонов не было возможности наступить друг на друга. Модуль tempfile может помочь с этим.

2 голосов
/ 06 апреля 2011

Два варианта, которые я вижу:

  1. Вы можете использовать lsof для поиска открытых файлов, чтобы найти файлы, которые пишет ProgramX.
  2. Другой подход заключается в запуске ProgramX во временном каталоге (см. tempfile для простого способа установки каталогов. Между запусками ProgramX вы можете очистить этот каталог или продолжать запрашивать новые временные каталоги, если вы планируете запускать несколько copieProgramX одновременно.
0 голосов
/ 06 апреля 2011

Если существует только один ProgramX* файл, то как насчет просто:

mv ProgramX* input.output
...