簡體   English   中英

使用POpen將變量發送到Stdin並將Stdout發送到變量

[英]Using POpen to send a variable to Stdin and to send Stdout to a variable

在shell腳本中,我們有以下命令:

/script1.pl < input_file| /script2.pl > output_file

我想使用模塊subprocess在Python中復制以上流。 input_file是一個大文件,我無法一次讀取整個文件。 這樣,我想將每行一個input_string到管道流中,並返回一個字符串變量output_string ,直到將整個文件流化為止。

以下是首次嘗試:

process = subprocess.Popen(["/script1.pl | /script2.pl"], stdin = subprocess.PIPE, stdout = subprocess.PIPE, shell = True)
process.stdin.write(input_string)
output_string = process.communicate()[0]

但是,使用process.communicate()[0]關閉流。 我想為將來的視頻流保持開放狀態 我嘗試使用process.stdout.readline()代替,但是程序掛起。

模擬/script1.pl < input_file | /script2.pl > output_file /script1.pl < input_file | /script2.pl > output_file shell命令,在Python中使用subprocess /script1.pl < input_file | /script2.pl > output_file模塊:

#!/usr/bin/env python
from subprocess import check_call

with open('input_file', 'rb') as input_file
    with open('output_file', 'wb') as output_file:
        check_call("/script1.pl | /script2.pl", shell=True,
                   stdin=input_file, stdout=output_file)

您可以基於17.1.4.2不用shell=True編寫它(盡管我在這里看不到原因) 從docs替換shell管道示例

#!/usr/bin/env python
from subprocess import Popen, PIPE

with open('input_file', 'rb') as input_file
    script1 = Popen("/script1.pl", stdin=input_file, stdout=PIPE)
with open("output_file", "wb") as output_file:
    script2 = Popen("/script2.pl", stdin=script1.stdout, stdout=output_file)
script1.stdout.close() # allow script1 to receive SIGPIPE if script2 exits
script2.wait()
script1.wait()

您還可以使用plumbum模塊在Python中獲取類似shell的語法

#!/usr/bin/env python
from plumbum import local

script1, script2 = local["/script1.pl"], local["/script2.pl"]
(script1 < "input_file" | script2 > "output_file")()

另請參閱如何使用subprocess.Popen通過管道連接多個進程?


如果要逐行讀取/寫入,則答案取決於要運行的具體腳本。 通常,如果不小心(例如由於緩沖問題) ,很容易死鎖發送/接收輸入/輸出。

如果輸入不取決於您的情況,那么可靠的跨平台方法是為每個流使用單獨的線程:

#!/usr/bin/env python
from subprocess import Popen, PIPE
from threading import Thread

def pump_input(pipe):
    try:
       for i in xrange(1000000000): # generate large input
           print >>pipe, i
    finally:
       pipe.close()

p = Popen("/script1.pl | /script2.pl", shell=True, stdin=PIPE, stdout=PIPE,
          bufsize=1)
Thread(target=pump_input, args=[p.stdin]).start()
try: # read output line by line as soon as the child flushes its stdout buffer
    for line in iter(p.stdout.readline, b''):
        print line.strip()[::-1] # print reversed lines
finally:
    p.stdout.close()
    p.wait()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM