Jak przesłać wywołanie podprocesu do pliku tekstowego?

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

Teraz mam skrypt, który uruchamiam. Kiedy go uruchamiam i trafia w tę linię, zaczyna drukować dane, ponieważ run.sh ma w sobie wydruki.

Jak przesłać to również do pliku tekstowego? (A także wydrukuj, jeśli to możliwe)

TIMEX
źródło

Odpowiedzi:

177

Jeśli chcesz zapisać dane wyjściowe do pliku, możesz użyć argumentu stdout z subprocess.call.

To trwa None, subprocess.PIPE, obiekt pliku lub deskryptora pliku. Pierwsza jest domyślna, stdout jest dziedziczona z rodzica (twojego skryptu). Drugi pozwala ci przeskakiwać z jednego polecenia / procesu do drugiego. Trzeci i czwarty to to, czego chcesz, aby dane wyjściowe zostały zapisane do pliku.

Musisz otworzyć plik z czymś podobnym openi przekazać liczbę całkowitą obiektu lub deskryptora pliku do call:

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

Domyślam się, że każdy poprawny obiekt podobny do pliku zadziała, jak gniazdo (sapnięcie :)), ale nigdy nie próbowałem.

Jak marcog wspomina w komentarzach, że możesz chcieć przekierować stderr, możesz przekierować to do tej samej lokalizacji co stdout za pomocą stderr=subprocess.STDOUT. Każda z wyżej wymienionych wartości również działa, możesz przekierować w inne miejsca.

Skurmedel
źródło
6
dlaczego podproces.call (["echo", "1", ">>", "t.txt"]) nie działa?
StackOverflowOfficial
7
@Goldname potrzebujesz powłoki do wykonywania przekierowań, więc: subprocess.call(["echo", "1", ">>", "t.txt"], shell=True)powinno działać.
Wes Mason,
@WesMason Dzięki, ale myślałem, że subprocess.call działa w taki sposób, jak kopiowanie i wklejanie do powłoki?
StackOverflowOficjalny
2
@Goldname nie, wszystko w podprocesie opiera się na podstawowej klasie Popen, która otwiera proces, shell = True wymusi wykonanie procesu w domyślnej powłoce systemu (np. / Bin / sh w systemach POSIX, która zwykle jest bash lub dash ), jest bezpieczniejszy w ten sposób, ponieważ nie jesteś otwarty na wszystkie dodatkowe funkcje zapewniane przez powłokę (cały sam język programowania, z własnymi exploitami, jeśli przekazuje dane dostarczone przez użytkownika). Sprawdź także, shlex.quoteczy przekazujesz jakiekolwiek potencjalnie brudne dane do podpowłoki.
Wes Mason,
4
Czy powinniśmy również zamknąć plik po zakończeniu? spowoduje to zamknięcie pliku, gdy skończymy: with open("blah.txt","w") as f: subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml", "/tmp/video_xml"], stdout=f) @Skurmedel
alper
19

Opcji popenmożna używać w programiecall

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

Więc...

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

Następnie możesz robić, co chcesz myoutput( przy okazji musiałby to być plik).

Możesz również zrobić coś bliższego takiemu wyjściu potokowemu.

dmesg | grep hda

byłoby:

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

Na stronie podręcznika Pythona jest mnóstwo uroczych, przydatnych informacji .

ocodo
źródło
-2

Możesz także po prostu wywołać skrypt z terminala, wypisując wszystko do pliku, jeśli to pomoże. Tą drogą:

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

Spowoduje to nadpisanie pliku. Możesz użyć, >>aby dołączyć do niego.

Jeśli chcesz, aby błędy były również rejestrowane w pliku, użyj &>>lub &>.

Danilo Martins
źródło