如何在Linux上使用帶管道的子程序模組?


在Python中,我們有**subprocess**模組,它允許我們使用額外的程序,並使開發人員的工作更加輕鬆。雖然還有其他模組提供與subprocess模組類似的功能,例如**os.spawn()、os.system()、os.popen()**等等,但推薦使用subprocess模組的原因是它比上面提到的所有其他類似模組都提供更高級別的介面。

為了能夠將管道與subprocess模組一起使用,我們首先需要了解subprocess模組的功能。

示例

讓我們考慮一個簡單的subprocess模組示例,我將在其中列印外部命令,甚至不與它互動。

考慮以下示例:

建立一個名為sample.py的python檔案,然後將以下程式碼放入該檔案中:

import subprocess
subprocess.call(['ls -ltr', '-1'], shell=True)

使用以下命令執行sample.py檔案:

python sample.py

輸出

$ python sample.py

__init__.py
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_call.py
subprocess_check_output.py
subprocess_check_output_error.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
...

現在,當我們談到使用subprocess模組時,我們最終會使用**Shell=True**標誌,在許多情況下必須避免這種情況,而且也不推薦。

例如:

def count_number_of_lines(website):
return subprocess.check_output('curl %s | wc -l' % website, shell=True)

如果我在上面的示例中傳遞任何網站的URL,它將返回該URL上可用的行數。

例如,如果我傳遞‘www.google.com’,那麼

輸出

'7
'

但這絕對不推薦,因為它允許shell注入,如果您關心網站的安全,這將是一場噩夢。

更好的方法是使用管道,為此,我們可以將上面示例中的程式碼更改為如下所示:

def count_number_of_lines(website):
   args1 = ['curl', website]
   args2 = ['wc', '-l']
   process_curl = subprocess.Popen(args1, stdout=subprocess.PIPE,
                  shell=False)
   process_wc = subprocess.Popen(args2, stdin=process_curl.stdout,
                  stdout=subprocess.PIPE, shell=False)
   process_curl.stdout.close()
   return process_wc.communicate()[0]

輸出

'7
'

更新於:2021年7月31日

362 次瀏覽

開啟您的職業生涯

完成課程獲得認證

開始學習
廣告