在日常开发中,有时需要在Python脚本中执行系统命令,Python有五种方式来执行系统命令,推荐使用第五种。
python执行系统命令的五种方式
方法1: os.system
这是最简单的方法,适合简单的业务场景,输入为完整命令字符串,命令执行结果输出到控制台;执行成功,返回值为0,失败返回值大于0。
import os
result = os.system("ls -a")
方法2:os.popen
和上面一个类似,输入完整的命令字符串,但是结果不会直接输出,会保存到返回值中,调用read()可以读取结果。
import os
result = os.popen("ls -a")
print(result.read())
方法3:subprocess.run
subprocess.run 是 Python 中 subprocess 模块的一个函数,用于运行子进程。它是 Python 3.5 版本引入的。subprocess.run 提供了一种简单的方式来替代较老的 subprocess.call 函数,更方便地运行子进程并等待其完成。执行命令后,运行结果保存在CompletedProcess类实例中,并返回。更加灵活,可以将命令返回的结果输出到指定的地方,比如输出到控制台、或者日志文件等。
import subprocess
# 定义要运行的命令
command = ["ls", "-l"]
# 使用 subprocess.run 运行命令, 如果不设置stdout参数,会默认输出到控制台
result = subprocess.run(command, stdout=subprocess.PIPE, text=True)
# 输出命令的结果
print("Return code:", result.returncode)
print("Output:\n", result.stdout)
这个例子中,我们定义了一个要运行的命令(列出当前目录的文件和文件夹),然后使用 subprocess.run 来运行它。stdout=subprocess.PIPE 参数指定将子进程的标准输出捕获,而 text=True 参数确保输出是文本形式。subprocess.run 的返回结果是一个 CompletedProcess 对象,包含了运行结果的一些信息,如返回码、标准输出等。请注意,subprocess.run 默认是同步执行的,即会等待子进程执行完成后再返回。如果你需要异步执行或更高级的控制,可以考虑使用 asyncio 模块或 subprocess.Popen 类。
stdout参数也可以设置为外部文件
同理,不设置stderr参数时,外部命令执行失败会直接抛出错误信息,将错误信息输出在控制台;一旦设置,则根据stderr参数进行重定向。
方法4:subprocess.call
subprocess.call 是 subprocess 模块中的一个函数,用于运行命令并等待其完成。它是相对较老的方法,而在较新版本的 Python 中,subprocess.run 被推荐用来替代 subprocess.call。这里不推荐使用也不做介绍了。
方法5:subprocess.Popen
subprocess.Popen 是 subprocess 模块中的一个类,用于创建和管理子进程。与 subprocess.call 和 subprocess.run 不同,subprocess.Popen 提供了更灵活的控制,允许你与子进程的输入、输出进行交互,以及对进程的其他方面进行更详细的配置。
下面是一个简单的使用示例:
import subprocess
# 定义要运行的命令
command = ["ls", "-l"]
# 使用 subprocess.Popen 创建子进程
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
# 等待子进程完成,并获取输出和错误
stdout, stderr = process.communicate()
# 输出子进程的标准输出和标准错误
print("Standard Output:\n", stdout)
print("Standard Error:\n", stderr)
# 获取子进程的返回码
return_code = process.returncode
print("Return code:", return_code)
在这个例子中,我们使用 subprocess.Popen 创建了一个子进程,指定了要运行的命令以及捕获标准输出和标准错误。然后,使用 communicate 方法等待子进程完成,并获取其输出和错误。
subprocess.Popen 的构造函数接受许多参数,允许你自定义子进程的各个方面。例如,你可以指定工作目录、环境变量、文件描述符、标准输入等。更多详细信息可以参考 Python 官方文档:subprocess.Popen。
需要注意的是,与 subprocess.call 和 subprocess.run 不同,subprocess.Popen 不会等待子进程完成,你需要显式调用 communicate 或其他等待方法来等待子进程完成。
总结
如果不知道用哪种就推荐使用subprocess.Popen,简单场景下用os.system就可以了。