Python subprocess模块详解
在Python编程中,subprocess模块是一个非常有用的工具,可以让我们在程序中轻松地启动新的进程、连接标准输入输出和错误流,并与它们进行交互。本文将详细介绍subprocess模块的基本用法、常见功能以及一些高级技巧。
1. subprocess模块基本用法
subprocess模块允许我们在Python程序中执行外部命令,比如调用系统命令、运行其他可执行文件等。它提供了多个函数和类来执行各种操作,常用的包括subprocess.run()
、subprocess.Popen()
等。
1.1 subprocess.run()
subprocess.run()
函数是Python 3.5及以上版本中引入的,它可以方便地运行命令并等待其完成。下面是一个简单的示例:
import subprocess
result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE)
print(result.stdout.decode())
上面的代码调用了ls -l
命令并将结果输出到标准输出流。stdout=subprocess.PIPE
参数表示将标准输出重定向到管道,result.stdout.decode()
用于解码并打印输出。
1.2 subprocess.Popen()
subprocess.Popen()
函数是一个更加灵活的接口,允许更多的控制选项。通过Popen
对象可以启动一个新的子进程,并与其进行交互。下面是一个示例:
import subprocess
p = subprocess.Popen(['echo', 'Hello, World!'], stdout=subprocess.PIPE)
output, _ = p.communicate()
print(output.decode())
在上面的代码中,我们使用Popen
对象执行了echo
命令,并通过communicate()
方法获取了命令的标准输出。
2. subprocess常见功能
2.1 输入输出重定向
在使用subprocess
模块时,经常需要控制进程的标准输入、输出和错误流。可以使用参数stdin
、stdout
和stderr
来重定向这些流,如下所示:
import subprocess
p = subprocess.Popen(['cat'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output, _ = p.communicate(input=b'Hello, World!')
print(output.decode())
上面的代码演示了如何使用subprocess
模块将字符串Hello, World!
写入cat
命令的标准输入,并读取其输出。
2.2 超时设置
有时候需要设置子进程的超时时间,避免进程长时间运行导致程序阻塞。可以使用timeout
参数来设置超时时间,例如:
import subprocess
try:
subprocess.run(['sleep', '3'], timeout=2)
except subprocess.TimeoutExpired:
print("Timeout expired")
上面的代码演示了如何限制sleep 3
命令执行的最长时间为2秒,超过时间会触发TimeoutExpired
异常。
2.3 并行执行多个命令
有时候可能需要并行执行多个命令,可以使用subprocess
模块创建多个子进程来实现。下面是一个示例:
import subprocess
# 创建两个子进程并行执行命令
p1 = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['wc', '-l'], stdin=p1.stdout, stdout=subprocess.PIPE)
output, _ = p2.communicate()
print(output.decode())
上面的代码中,我们创建了两个子进程,一个用于执行ls -l
命令,另一个用于执行wc -l
命令,然后通过管道连接它们的输入输出流。
3. subprocess高级技巧
3.1 使用shell参数
在调用subprocess
模块函数时,可以通过shell=True
参数来执行shell命令。但需要注意安全性,避免被注入攻击。示例如下:
import subprocess
output = subprocess.run('ls -l', shell=True, stdout=subprocess.PIPE)
print(output.stdout.decode())
3.2 交互式进程
有时候需要在Python程序中与外部进程进行交互,比如输入密码、确认等。可以使用subprocess
模块的stdin
, stdout
, stderr
属性来实现。示例如下:
import subprocess
p = subprocess.Popen(['sudo', 'passwd', 'root'], stdin=subprocess.PIPE)
p.stdin.write(b'new_password\n')
p.stdin.write(b'new_password\n')
p.stdin.flush()
p.stdin.close()
p.wait()
上面的代码演示了如何在Python程序中执行sudo passwd root
命令并输入新密码,完成互动式操作。