Як перевести виклик підпроцесу в текстовий файл?


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

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

Як також перенести це в текстовий файл? (А також надрукуйте, якщо це можливо)

Відповіді:


176

Якщо ви хочете записати вихідні дані у файл, ви можете використовувати stdout -argument of 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)

Я припускаю, що будь-який дійсний файлоподібний об'єкт буде працювати, як сокет (задихається :)), але я ніколи не пробував.

Як Марког згадує в коментарях, ви можете також перенаправити stderr, ви можете перенаправити його туди ж, де і stdout stderr=subprocess.STDOUT. Будь-яке із вищезазначених значень також працює, ви можете перенаправити в різні місця.


6
чому subprocess.call (["echo", "1", ">>", "t.txt"]) не працює?
StackOverflowOfficial

7
@Goldname вам потрібна оболонка для переспрямування, тому: subprocess.call(["echo", "1", ">>", "t.txt"], shell=True)має працювати.
Wes Mason

@WesMason Дякую, але я думав, що subprocess.call працював таким чином, що в основному нагадував копіювання та вставлення в оболонку?
StackOverflowOfficial

2
@Goldname nah, все в підпроцесі покладається на базовий клас Popen, який відкриває процес, shell = True змусить процес виконуватися в системній оболонці за замовчуванням (наприклад, / bin / sh у системах POSIX, що зазвичай є bash або dash ), це набагато безпечніше, оскільки ви не відкриті для всієї додаткової функціональності, яку надає оболонка (ціла мова програмування сама по собі, з власними експлойтами при передачі даних, наданих користувачем). Також подивіться на те, shlex.quoteчи передаєте ви будь-які, можливо, брудні дані до підшелупки.
Wes Mason

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

Це перезапише файл. Можна використовувати>> щоб додати до нього.

Якщо ви хочете, щоб помилки також реєструвались у файлі, використовуйте &>>або &>.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.