如何在 Linux 上使用带有管道的子进程模块?

在 Python 中,我们有subprocess模块,它允许我们处理额外的进程,并使我们作为开发人员的工作更容易。虽然有提供给我们的其他模块也提供类似功能的子模块,如等等,但建议在所有这些模块的子进程的原因是因为它比所有其他高级接口的发行上面提到的类似模块。os.spawn()os.system()os.popen()

为了能够将管道与子流程模块一起使用,我们首先需要了解子流程模块的作用。

示例

让我们考虑 subprocess 模块的一个简单示例,我将在其中打印外部命令,甚至不与其交互。

考虑下面显示的例子 -

创建一个名为的 python 文件sample.py,然后将下面显示的以下代码放入该文件中 -

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\n'

但这绝对不推荐,因为它允许 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\n'