一文详解Python中subprocess模块的用法

 更新时间:2023年11月09日 09:17:12   作者:涛哥聊Python  
Python的subprocess模块是一个非常强大的工具,用于启动和与外部进程进行交互,本文将为大家详细介绍 subprocess模块的各个方面,希望对大家有所帮助

Python的subprocess模块是一个非常强大的工具,用于启动和与外部进程进行交互。它允许执行外部命令、访问系统Shell、管道数据、捕获输出和错误信息,以及更多。

本文详细介绍 subprocess模块的各个方面,包括如何执行外部命令、传递参数、处理输入输出、错误处理以及一些高级应用。

1. 介绍

subprocess模块是Python的标准库中的一部分,它允许与外部进程进行交互。这对于执行系统命令、调用其他可执行文件、处理数据流以及与其他进程通信非常有用。无论是需要执行简单的命令还是需要与复杂的外部程序进行交互,subprocess都可以胜任。

在接下来的内容中,我们将学习如何使用subprocess模块来执行外部命令、处理输入输出、捕获错误信息,并探讨一些高级用法。我们还会讨论一些安全性方面的注意事项,以确保您的程序不受到潜在的安全漏洞的威胁。

2. 执行外部命令

2.1 使用subprocess.run()

subprocess.run()是Python 3.5及更高版本引入的函数,用于运行外部命令并等待其完成。

以下是一个简单的示例,演示如何使用subprocess.run()来执行ls命令并获取其输出:

import subprocess

result = subprocess.run(["ls", "-l"], stdout=subprocess.PIPE, text=True)
print(result.stdout)

在上面的示例中,subprocess.run()接受一个包含命令及其参数的列表,通过stdout=subprocess.PIPE参数捕获标准输出,并使用text=True参数指定输出为文本。最后,我们打印了result.stdout以获取ls -l命令的输出。

2.2 使用subprocess.Popen()

subprocess.Popen()提供了更多的灵活性,允许与进程进行交互,而不仅仅是等待它完成。

以下是一个使用subprocess.Popen()的示例,演示如何执行外部命令并获取其输出:

import subprocess

# 执行命令
process = subprocess.Popen(["ls", "-l"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

# 读取标准输出和错误
out, err = process.communicate()

print("标准输出:")
print(out)

print("标准错误:")
print(err)

在上面的示例中,首先使用subprocess.Popen()来启动进程,并指定stdout=subprocess.PIPEstderr=subprocess.PIPE以捕获标准输出和标准错误。然后,使用process.communicate()方法来等待进程完成并获取其输出。

2.3 指定执行路径

使用cwd参数来指定执行外部命令的工作目录。例如,要在特定目录中执行命令,可以这样做:

import subprocess

result = subprocess.run(["ls", "-l"], stdout=subprocess.PIPE, text=True, cwd="/path/to/directory")
print(result.stdout)

这将在/path/to/directory目录中执行ls -l命令。

2.4 传递参数

如果命令需要接受参数,可以将它们作为列表的一部分传递给subprocess.run()subprocess.Popen()

例如,要将文件名作为参数传递给命令,可以这样做:

import subprocess

filename = "example.txt"
result = subprocess.run(["cat", filename], stdout=subprocess.PIPE, text=True)
print(result.stdout)

这将执行cat example.txt命令,其中filename是文件名。

3. 处理输入输出

3.1 标准输入

subprocess模块还可以将数据传递给外部命令的标准输入。要实现这一点,可以使用stdin参数,并将其设置为一个文件对象或一个字节串。

import subprocess

input_data = "Hello, subprocess!"
result = subprocess.run(["grep", "subprocess"], input=input_data, stdout=subprocess.PIPE, text=True)
print(result.stdout)

在上面的示例中,使用input_data将数据传递给grep命令的标准输入,并搜索包含"subprocess"的行。

3.2 标准输出

前面的示例中,已经看到如何捕获外部命令的标准输出。通过使用stdout参数,可以将标准输出重定向到文件、字节串或文件对象。

import subprocess

output_file = open("output.txt", "w")
result = subprocess.run(["ls", "-l"], stdout=output_file, text=True)
output_file.close()

在上面的示例中,我们将ls -l命令的标准输出重定向到一个名为output.txt的文件。

3.3 标准错误

与标准输出类似,subprocess还可以捕获标准错误信息。要捕获标准错误,请使用stderr参数。

import subprocess

result = subprocess.run(["ls", "/nonexistent"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print("标准输出:")
print(result.stdout)
print("标准错误:")
print(result.stderr)

在上面的示例中,执行ls /nonexistent命令,该命令会产生一个错误,并将标准输出和标准错误信息捕获到result.stdoutresult.stderr中。

4. 错误处理

执行外部命令时,通常需要处理错误。以下是一些处理错误的常用方法:

4.1 检查返回码

subprocess.run()subprocess.Popen()返回一个CompletedProcessPopen对象,其中包含有关命令执行的信息,包括返回码。返回码为0表示命令成功执行,非零返回码表示发生错误。

import subprocess

result = subprocess.run(["ls", "/nonexistent"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode != 0:
    print("命令执行失败。")
    print("标准错误:")
    print(result.stderr)

在上面的示例中,检查result.returncode是否为0,如果不是,就表示命令执行失败。

4.2 捕获错误输出

有时,错误信息可能不仅仅包含在返回码中,还包含在标准错误输出中。可以捕获标准错误输出并检查其中的信息。

import subprocess

result = subprocess.run(["ls", "/nonexistent"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode != 0:
    print("命令执行失败。")
    print("错误信息:")
    print(result.stderr)

在上面的示例中,我们捕获标准错误输出,并在发生错误时打印它。

5. 管道和重定向

subprocess还可以创建管道,将一个命令的输出连接到另一个命令的输入。这在处理复杂的数据处理任务时非常有用。

例如,要将一个命令的输出传递给另一个命令,可以这样做:

import subprocess

# 创建第一个命令的进程
process1 = subprocess.Popen(["ls", "/path/to/directory"], stdout=subprocess.PIPE, text=True)

# 创建第二个命令的进程,将第一个命令的输出连接到它的输入
process2 = subprocess.Popen(["grep", "search_term"], stdin=process1.stdout, stdout=subprocess.PIPE, text=True)

# 从第二个命令的标准输出中读取结果
result = process2.communicate()[0]
print(result)

在上面的示例中,首先创建第一个命令的进程,然后创建第二个命令的进程,并将第一个命令的输出连接到第二个命令的输入。

6. 高级应用

6.1 同时读写标准输入输出

subprocess模块同时读取和写入标准输入和输出。这对于与外部进程进行双向通信非常有用。

以下是一个示例,演示如何使用subprocess进行双向通信:

import subprocess

# 创建命令进程
process = subprocess.Popen(["python", "-u"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, universal_newlines=True)

# 写入数据到标准输入
process.stdin.write("print('Hello from child process')\n")
process.stdin.flush()

# 读取并打印标准输出
output, errors = process.communicate()
print("标准输出:")
print(output)

# 打印标准错误
print("标准错误:")
print(errors)

在上面的示例中,创建了一个子进程,然后向其标准输入写入Python代码,并捕获其标准输出和标准错误。

6.2 超时处理

subprocess还允许您设置执行命令的超时时间,以防止命令运行时间过长。要实现这一点,您可以使用timeout参数。

例如:

import subprocess

try:
    result = subprocess.run(["sleep", "10"], timeout=5, stdout=subprocess.PIPE, text=True)
    print(result.stdout)
except subprocess.TimeoutExpired:
    print("命令执行超时。")

在上面的示例中,试图运行sleep 10命令,但由于设置了5秒的超时时间,当命令运行时间超过5秒时,将引发subprocess.TimeoutExpired异常。

6.3 使用Shell命令

默认情况下,subprocess不会使用Shell来执行命令。这是出于安全考虑,以防止潜在的Shell注入攻击。但有些情况下,可能需要使用Shell来执行命令,可以将shell参数设置为True

import subprocess

# 使用Shell执行命令
result = subprocess.run("ls -l | grep .txt", shell=True, stdout=subprocess.PIPE, text=True)
print(result.stdout)

在上面的示例中,我们使用Shell来执行ls -l | grep .txt命令。

7. 安全性注意事项

在执行外部命令时,请务必小心处理输入,以防止潜在的安全漏洞。避免将不受信任的数据传递给subprocess,以免受到命令注入攻击。

确保了解正在执行的命令及其参数,以避免潜在的风险。

总结

Python的subprocess模块提供了强大的工具,允许与外部进程进行交互。可以使用它执行外部命令、传递参数、处理输入输出和错误信息,以及支持管道和重定向。这为编写需要与外部程序进行通信的Python应用程序提供了关键的功能。

subprocess模块是Python中处理外部进程交互的重要工具,但在使用时需要注意安全性问题,特别是在处理不受信任的输入时。熟练掌握这一模块,将有助于编写更强大和安全的Python应用程序,能够与外部程序进行有效通信。

以上就是一文详解Python中subprocess模块的用法的详细内容,更多关于Python subprocess的资料请关注脚本之家其它相关文章!

相关文章

  • Python collections模块的使用方法

    Python collections模块的使用方法

    这篇文章主要介绍了Python collections模块的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • Python推导式之字典推导式和集合推导式使用体验

    Python推导式之字典推导式和集合推导式使用体验

    这篇文章主要为大家介绍了Python推导式之字典推导式和集合推导式使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • 详解Python 函数如何重载?

    详解Python 函数如何重载?

    这篇文章主要介绍了Python函数重载,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 浅谈Python里面None True False之间的区别

    浅谈Python里面None True False之间的区别

    这篇文章主要介绍了浅谈Python里面None True False之间的区别,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • Python NumPy数组利器之np.zeros函数详解与应用实例

    Python NumPy数组利器之np.zeros函数详解与应用实例

    在Python的科学计算库NumPy中,numpy.zeros()是一个非常重要的函数,它用于创建一个指定形状和数据类型的全零数组,这篇文章主要给大家介绍了关于Python NumPy数组利器之np.zeros函数详解与应用实例的相关资料,需要的朋友可以参考下
    2024-06-06
  • pytorch torch运算操作示例详解

    pytorch torch运算操作示例详解

    这篇文章主要介绍了pytorch torch运算的相关知识,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-06-06
  • 在pyqt5中展示pyecharts生成的图像问题

    在pyqt5中展示pyecharts生成的图像问题

    本文通过一个实际的散点图案例,展示了如何使用pyqt5嵌套一个pyecharts图层的方法,通过这个技巧,可以在pyqt5的框架中也实现精美的数据可视化的功能模块,感兴趣的朋友一起看看吧
    2022-01-01
  • PyCharm+Qt Designer+PyUIC安装配置教程详解

    PyCharm+Qt Designer+PyUIC安装配置教程详解

    这篇文章主要介绍了PyCharm+Qt Designer+PyUIC安装配置教程详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-06-06
  • Python的turtle绘图库使用基础

    Python的turtle绘图库使用基础

    turtle库是Python语言中一个很流行的绘制图像的函数库,想象一个小乌龟,它根据一组函数指令的控制,在这个平面坐标系中移动,从而在它爬行的路径上绘制了图形,需要的朋友可以参考下
    2023-04-04
  • Matplotlib绘制雷达图和三维图的示例代码

    Matplotlib绘制雷达图和三维图的示例代码

    这篇文章主要介绍了Matplotlib绘制雷达图和三维图的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01

最新评论