Как передать вызов подпроцесса текстовому файлу?

97
subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml",  "/tmp/video_xml"])

Правильно, теперь у меня есть сценарий, который я запускаю. Когда я запускаю его и он попадает в эту строку, он начинает печатать, потому что в run.sh есть отпечатки.

Как мне передать это также в текстовый файл? (А также распечатать, если есть возможность)

TIMEX
источник

Ответы:

179

Если вы хотите записать вывод в файл, вы можете использовать stdout -аргумент subprocess.call.

Он принимает None, subprocess.PIPE, объект файла или дескриптора файла. Первый - по умолчанию, stdout наследуется от родителя (вашего скрипта). Второй позволяет передавать от одной команды / процесса к другой. Третий и четвертый - это то, что вы хотите, чтобы результат был записан в файл.

Вам нужно открыть файл с чем-то вроде openи передать целое число дескриптора объекта или файла в call:

f = open("blah.txt", "w")
subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml",  "/tmp/video_xml"], stdout=f)

Я предполагаю, что любой допустимый файловый объект будет работать, например сокет (вздох :)), но я никогда не пробовал.

Как отмечает marcog в комментариях, вы также можете перенаправить stderr, вы можете перенаправить его в то же место, что и stdout, с помощью stderr=subprocess.STDOUT. Любое из вышеперечисленных значений также работает, вы можете перенаправить в разные места.

Скурмедель
источник
6
почему не работает subprocess.call (["echo", "1", ">>", "t.txt"])?
StackOverflowOfficial
7
@Goldname вам нужна оболочка для перенаправления, поэтому: subprocess.call(["echo", "1", ">>", "t.txt"], shell=True)должно работать.
Уэс Мейсон
@WesMason Спасибо, но я думал, что subprocess.call работает так, как будто копирует и вставляет в оболочку?
StackOverflowOfficial
2
@Goldname нет, все в подпроцессе полагается на базовый класс Popen, который открывает процесс, shell = True заставит процесс выполняться в системной оболочке по умолчанию (например, / bin / sh в системах POSIX, обычно это bash или тире ), это более безопасно, поскольку вы не открыты для всех дополнительных функций, предоставляемых оболочкой (целый язык программирования сам по себе, со своими собственными эксплойтами при передаче данных, предоставленных пользователем). Также посмотрите shlex.quote, не передаете ли вы какие-либо потенциально грязные данные в подоболочку.
Уэс Мейсон
4
Должны ли мы также закрыть файл после того, как мы закончим? это будет закрывать файл после того, как мы сделали: with open("blah.txt","w") as f: subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml", "/tmp/video_xml"], stdout=f) @Skurmedel
Alper
19

Параметры popenможно использовать вcall

args, 
bufsize=0, 
executable=None, 
stdin=None, 
stdout=None, 
stderr=None, 
preexec_fn=None, 
close_fds=False, 
shell=False, 
cwd=None, 
env=None, 
universal_newlines=False, 
startupinfo=None, 
creationflags=0

Так...

subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml",  "/tmp/video_xml"], stdout=myoutput)

Затем вы можете делать то, что хотите myoutput(кстати, это должен быть файл).

Кроме того, вы можете сделать что-то похожее на конвейерный вывод, подобный этому.

dmesg | grep hda

было бы:

p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]

На странице руководства по python есть много прекрасной и полезной информации .

окодо
источник
-2

Вы также можете просто вызвать сценарий из терминала, выводя все в файл, если это поможет. Сюда:

$ /path/to/the/script.py > output.txt

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

Если вы хотите, чтобы ошибки также регистрировались в файле, используйте &>>или &>.

Данило Мартинс
источник