Bagaimana cara menyalurkan panggilan subproses ke file teks?

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

Sekarang saya memiliki script yang saya jalankan. Ketika saya menjalankannya dan mencapai baris ini, itu mulai mencetak barang karena run.sh memiliki cetakan di dalamnya.

Bagaimana cara menyalurkan ini ke file teks juga? (Dan juga mencetak, jika memungkinkan)

TIMEX
sumber

Jawaban:

177

Jika Anda ingin menulis output ke file, Anda dapat menggunakan stdout -argument of subprocess.call.

Dibutuhkan None,, subprocess.PIPEobjek file atau deskriptor file. Yang pertama adalah defaultnya, stdout diwarisi dari induk (skrip Anda). Yang kedua memungkinkan Anda untuk menyalurkan dari satu perintah / proses ke yang lain. Yang ketiga dan keempat adalah apa yang Anda inginkan, agar keluaran ditulis ke file.

Anda perlu membuka file dengan sesuatu seperti opendan meneruskan integer deskriptor objek atau file ke call:

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

Saya menduga objek seperti file yang valid akan berfungsi, seperti soket (terkesiap :)), tetapi saya belum pernah mencoba.

Seperti yang disebutkan oleh marcog di komentar Anda mungkin juga ingin mengarahkan stderr, Anda dapat mengarahkan ini ke lokasi yang sama dengan stdout stderr=subprocess.STDOUT. Salah satu nilai yang disebutkan di atas berfungsi juga, Anda dapat mengarahkan ke tempat yang berbeda.

Skurmedel
sumber
6
mengapa subprocess.call (["echo", "1", ">>", "t.txt"]) tidak berfungsi?
StackOverflowOfficial
7
@Goldname Anda memerlukan shell untuk melakukan pengalihan, jadi: subprocess.call(["echo", "1", ">>", "t.txt"], shell=True)seharusnya berfungsi.
Wes Mason
@WesMason Terima kasih, tetapi saya pikir subprocess.call bekerja dengan cara yang pada dasarnya seperti menyalin dan menempel ke shell?
StackOverflowOfficial
2
@Goldname nah, semua yang ada di subproses bergantung pada kelas Popen yang mendasari, yang membuka proses, shell = True akan memaksa proses untuk dieksekusi di shell default sistem (misalnya / bin / sh pada sistem POSIX, yang biasanya bash atau tanda hubung ), cara ini lebih aman karena Anda tidak terbuka untuk semua fungsionalitas tambahan yang disediakan oleh shell (keseluruhan bahasa pemrograman itu sendiri, dengan eksploitnya sendiri jika meneruskan data yang disediakan pengguna). Lihat juga shlex.quoteapakah Anda mengirimkan data yang mungkin kotor ke subkulit.
Wes Mason
4
Haruskah kita juga menutup file setelah selesai? ini akan menutup file setelah kita selesai: with open("blah.txt","w") as f: subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml", "/tmp/video_xml"], stdout=f) @Skurmedel
alper
19

Opsi untuk popendapat digunakan dalamcall

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

Begitu...

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

Kemudian Anda dapat melakukan apa yang Anda inginkan myoutput(yang perlu berupa file btw).

Selain itu, Anda dapat melakukan sesuatu yang lebih dekat dengan keluaran yang disalurkan seperti ini.

dmesg | grep hda

akan menjadi:

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

Ada banyak info bagus dan berguna di halaman manual python .

ocodo
sumber
-2

Anda juga bisa memanggil skrip dari terminal, mengeluarkan semuanya ke file, jika itu membantu. Cara ini:

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

Ini akan menimpa file. Anda dapat menggunakan >>untuk menambahkannya.

Jika Anda ingin kesalahan dicatat di file juga, gunakan &>>atau &>.

Danilo Martins
sumber