python subprocess.run()、subprocess.Popen()、subprocess.check_output()(执行系统命令、启动新的进程、连接到子进程的输入/输出管道)

这篇具有很好参考价值的文章主要介绍了python subprocess.run()、subprocess.Popen()、subprocess.check_output()(执行系统命令、启动新的进程、连接到子进程的输入/输出管道)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


python subprocess.run()、subprocess.Popen()、subprocess.check_output()(执行系统命令、启动新的进程、连接到子进程的输入/输出管道),Python,linux,python,服务器

python subprocess

Python的subprocess模块是用于创建和管理子进程的模块。它提供了一种在Python中调用外部命令的方式,可以执行系统命令、启动新的进程、连接到子进程的输入/输出管道等。

基本函数

subprocess.run

subprocess.run(args, *, stdin=None, input=None, stdout=None,
               stderr=None, capture_output=False, text=None,
               check=False, timeout=None, encoding=None, errors=None)
  • 运行指定的命令,并等待其完成。args参数是一个字符串或列表,表示要执行的命令和参数。
  • stdin、stdout和stderr参数分别用于指定子进程的标准输入、标准输出和标准错误输出的处理方式。
  • capture_output参数用于指定是否捕获子进程的输出。
  • check参数用于指定是否检查子进程的返回值,如果返回值不为0,则会抛出CalledProcessError异常。
  • timeout参数用于指定子进程的超时时间。
  • encoding和errors参数用于指定输入/输出的编码方式和错误处理方式。
示例(只可以捕获标准输出,标准错误不知道咋获取,异常也没抛。。。以后再看,现在有事)
import subprocess


def execute_update_ip_sh(ip):
    """
    执行修改配置文件 ip 脚本,将会修改ky_ai_solution.json、nginx.conf、vsftpd.conf 等文件中的ip
    """
    try:
        # 构建命令
        command = ['/ky/update_ip.sh', ip]

        # 执行命令并获取输出(这个出错直接就抛异常了,不能捕获标准输出和标准错误)
        # result = subprocess.check_output(command, universal_newlines=True)

        result = subprocess.run(command, stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE, universal_newlines=True)

        # 打印脚本的输出
        print(f"[{command}] 标准输出:", result.stdout)

        # 打印脚本的错误输出(打印不出来)
        print(f"[{command}] 标准错误输出:", result.stderr)

        # 执行成功,返回True
        return result.returncode == 0
    # except subprocess.CalledProcessError as e:
    except Exception as e:
        # 执行失败,返回False
        print(e)
        print("ddddddddddddddddddddddddddddddddddddddd")
        return False


if __name__ == "__main__":
    execute_update_ip_sh("192.168.1.140")

python subprocess.run()、subprocess.Popen()、subprocess.check_output()(执行系统命令、启动新的进程、连接到子进程的输入/输出管道),Python,linux,python,服务器

subprocess.Popen

subprocess.Popen(args, bufsize=-1, executable=None, 
                 stdin=None, stdout=None, stderr=None, 
                 preexec_fn=None, close_fds=True, 
                 shell=False, cwd=None, env=None, 
                 universal_newlines=False, startupinfo=None, 
                 creationflags=0, restore_signals=True, 
                 start_new_session=False, pass_fds=(), *, 
                 encoding=None, errors=None)
  • 启动一个新的进程,并返回一个Popen对象,可以用于与子进程进行交互。
  • args参数和其他参数的含义与subprocess.run()函数相同。
subprocess.Popen参数解释
- args:要执行的命令及其参数。可以是一个字符串或一个字符串列表。
- bufsize:指定缓冲区的大小。默认值为-1,表示使用系统默认的缓冲区大小。
- executable:指定要执行的可执行文件的路径。默认值为None,表示使用系统默认的可执行文件。
- stdin:指定子进程的标准输入。可以是一个文件对象或一个文件描述符。默认值为None,表示使用父进程的标准输入。
- stdout:指定子进程的标准输出。可以是一个文件对象或一个文件描述符。默认值为None,表示使用父进程的标准输出。
- stderr:指定子进程的标准错误输出。可以是一个文件对象或一个文件描述符。默认值为None,表示使用父进程的标准错误输出。
- preexec_fn:在子进程执行前调用的可调用对象。默认值为None,表示不调用任何函数。
示例:使用preexec_fn来将Popen对象绑定进程组

当使用shell=True时,subprocess.Popen()函数创建的子进程实际上是一个shell进程,而不是直接执行的命令。因此,向Popen对象发送信号并不能直接影响到子进程。

如果需要向通过shell执行的命令发送信号,可以使用os.killpg()函数来发送信号给进程组。具体步骤如下:

  1. 创建Popen对象时,设置preexec_fn=os.setsid,以创建一个新的进程组。
  2. 使用os.killpg()函数发送信号给进程组。

下面是一个示例,演示了如何向通过shell执行的命令发送信号:

import subprocess
import os
import signal

# 通过shell执行命令
process = subprocess.Popen('sleep 10', shell=True, preexec_fn=os.setsid)

# 发送信号给进程组
os.killpg(os.getpgid(process.pid), signal.SIGTERM)

在这个示例中,首先通过subprocess.Popen()函数创建了一个通过shell执行的命令。在创建Popen对象时,通过preexec_fn=os.setsid设置了preexec_fn参数,以创建一个新的进程组。

然后,使用os.killpg()函数发送信号给进程组。在这个示例中,发送了SIGTERM信号,即终止信号。

需要注意的是,向进程组发送信号会影响到进程组中的所有进程。因此,如果有多个通过shell执行的命令,它们都属于同一个进程组,发送信号时需要注意。

- close_fds:指定是否在子进程中关闭父进程中打开的文件描述符。默认值为True,表示关闭文件描述符。
- shell:指定是否通过shell来执行命令。默认值为False,表示不通过shell执行命令。

shell参数设置为True时,表示通过shell来执行命令。这意味着可以使用shell的语法和功能,比如管道、重定向、通配符等。在这种情况下,args参数可以是一个字符串,表示要执行的完整命令。

shell参数设置为False时,表示不通过shell来执行命令。这是默认的行为。在这种情况下,args参数应该是一个字符串列表,其中第一个元素是要执行的命令,后续元素是命令的参数。

需要注意的是,使用shell=True时,应该谨慎处理输入参数,避免命令注入等安全问题。应该始终对用户输入进行验证和过滤,避免直接将用户输入拼接到命令中。

下面是一个示例,演示了shell参数的用法:

import subprocess

# 通过shell执行命令
subprocess.Popen('ls -l', shell=True)

# 不通过shell执行命令
subprocess.Popen(['ls', '-l'])

在这个示例中,第一个Popen()函数调用通过shell执行了ls -l命令,而第二个Popen()函数调用不通过shell执行了ls -l命令。

使用shell执行和不使用shell执行的差异(以管道为例)
  • 使用shell执行:

下面是一个示例,演示了如何通过shell执行命令并使用管道:

import subprocess

# 通过shell执行命令并使用管道
process = subprocess.Popen('ls -l | grep .txt', shell=True)

# 等待子进程结束
process.wait()

在这个示例中,通过subprocess.Popen()函数的shell参数设置为True,表示通过shell执行命令。然后,可以使用shell的管道语法|将两个命令连接起来,实现输出过滤。

  • 不使用shell执行:
import subprocess

# 不通过shell执行命令并使用管道
command1 = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
command2 = subprocess.Popen(['grep', '.txt'], stdin=command1.stdout, stdout=subprocess.PIPE)

# 获取命令2的输出
output = command2.communicate()[0]

# 打印输出结果
print(output.decode())

在这个示例中,首先创建了两个Popen()对象,分别对应两个命令。command1执行了ls -l命令,并将输出通过管道传递给command2command2执行了grep .txt命令,并将结果输出到标准输出。

通过command2.communicate()方法获取命令2的输出,并将其打印出来。

不通过shell执行命令时,需要手动设置命令之间的输入输出关系,以及处理命令的输出。这需要更多的代码来实现,但也提供了更多的灵活性和控制能力。

- cwd:指定子进程的当前工作目录。默认值为None,表示使用父进程的当前工作目录。
- env:指定子进程的环境变量。可以是一个字典,表示环境变量的键值对。默认值为None,表示使用父进程的环境变量。
- universal_newlines:指定是否将输入/输出流以文本模式打开。默认值为False,表示以二进制模式打开。
- startupinfo:指定子进程的启动信息。可以是一个subprocess.STARTUPINFO对象,用于设置子进程的一些属性。默认值为None。
- creationflags:指定子进程的创建标志。默认值为0,表示使用默认的创建标志。
- restore_signals:指定是否在子进程中恢复信号处理程序。默认值为True,表示恢复信号处理程序。
- start_new_session:指定是否在新的会话中启动子进程。默认值为False,表示在当前会话中启动子进程。
- pass_fds:指定要传递给子进程的文件描述符列表。默认值为(),表示不传递文件描述符。
- encoding:指定输入/输出的编码方式。默认值为None,表示使用系统默认的编码方式。
- errors:指定输入/输出的错误处理方式。默认值为None,表示使用系统默认的错误处理方式。
总结

subprocess.Popen()函数会返回一个Popen对象,可以用于与子进程进行交互。Popen对象具有一些常用的方法和属性,比如communicate()wait()poll()terminate()kill()stdoutstderrreturncode等。

Popen对象的常用方法和属性
  • communicate(input=None, timeout=None):与子进程进行交互,发送输入并获取输出。
  • wait():等待子进程结束,并返回其返回值。
  • poll():检查子进程是否结束,如果结束则返回其返回值,否则返回None。
  • terminate():终止子进程。
  • kill():杀死子进程。
  • stdout:子进程的标准输出。
  • stderr:子进程的标准错误输出。
  • returncode:子进程的返回值。

下面是一个使用subprocess模块的示例,演示了如何执行一个系统命令并获取其输出:

import subprocess

# 执行系统命令
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)

# 获取命令的输出
output = result.stdout
print(output)

以上代码会执行ls -l命令,并将其输出打印出来。

需要注意的是,subprocess模块在执行外部命令时,存在一定的安全风险,特别是在使用shell=True参数时。因此,在使用subprocess模块时,应该谨慎处理输入参数,避免命令注入等安全问题。

subprocess.check_output

subprocess.check_output函数是Python标准库subprocess模块中的一个函数,用于执行系统命令并返回命令的输出结果。

它的用法是:

subprocess.check_output(args, *, stdin=None, stderr=None, 
                        shell=False, universal_newlines=False)

其中,args是一个字符串或者字符串列表,表示要执行的命令及其参数。stdinstderrshelluniversal_newlines是可选参数,用于控制输入、错误输出、是否使用shell以及输出结果的编码方式。

check_output函数会执行指定的命令,并等待命令执行完成。如果命令执行成功,它会返回命令的输出结果(以字节字符串的形式),如果命令执行失败,它会抛出一个CalledProcessError异常。

在上述代码中,subprocess.check_output函数被用于执行一些系统命令,如ip addr showip route show,以获取当前以太网接口的IP配置信息。文章来源地址https://www.toymoban.com/news/detail-699275.html

到了这里,关于python subprocess.run()、subprocess.Popen()、subprocess.check_output()(执行系统命令、启动新的进程、连接到子进程的输入/输出管道)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python subprocess执行外部命令常用方法

    subprocess模块是Python标准库中的一个模块,用于创建和控制子进程。它提供了一种在Python程序中调用其他外部命令、执行系统命令和与系统进程进行交互的方法。常用的有两种方法:subprocess.run(),subprocess.Popen() 1. subprocess.run()方法 subprocess.run()是subprocess模块中一个常用的函数,

    2024年02月06日
    浏览(31)
  • 使用python的subprocess执行命令、交互、等待、是否结束、解析JSON结果

    Python的subprocess模块提供了一种在Python中调用外部命令的方法。它允许您在Python程序中启动新进程,连接到它们的输入/输出/错误管道,并等待它们完成。 下面是一些subprocess模块的常用用法: 运行外部命令并获取输出: 运行外部命令并获取返回值: 运行外部命令并将输出重

    2024年02月08日
    浏览(51)
  • error: subprocess-exited-with-error × python setup.py egg_info did not run successfully.报错

    报错的具体信息: 网上找的改正方法是: pip install --upgrade setuptools 但是不行,最后仔细看了报错信息,谜底就在谜面上啊!Here is how to fix this error in the main use cases:这一行给出了修补方法,我直接简单粗暴整最后一个。 在环境中加入SKLEARN_ALLOW_DEPRECATED_SKLEARN_PACKAGE_INSTALL=True这

    2024年01月19日
    浏览(38)
  • subprocess.run方法

    subprocess.run 是 Python 中用于在程序中运行其他程序的方法。它是 Python 3.5 版本引入的,可以用来替代旧版本中的 subprocess.call 和 subprocess.check_call 等函数。 使用 subprocess.run 方法,你可以很方便地在 Python 中调用其他命令行程序,并且能够简单地获取命令的输出结果。此外,该方

    2024年02月12日
    浏览(25)
  • 【已解决】pip subprocess to install build dependencies did not run successfully.

    不要输入版本号。 例如 pandas==1.0.5,安装这个的时候就会出现这个问题,但是当我去掉版本号,只用命令conda install pandas 来进行安装时就不会产生这个报错。同理scipy==1.5.0也是。 用了将近一天的时间来配置环境,尝试了各种方法,结果竟是这样解决就行了,我是废物。

    2024年02月12日
    浏览(37)
  • keil错误和解决办法(1):FCARM - Output Name not specified, please check ‘Options for Target - Utilities‘

    这个错误是由于新导入到工程内的文件,未被正确识别而引发的错误 报错: FCARM - Output Name not specified, please check ‘Options for Target - Utilities’ 原因:用户的.c和.h文件往往都是新建txt,然后改的后缀,这样的文件被导入keil后,有可能会被识别成image file。 在新导入到keil中的文

    2024年02月16日
    浏览(37)
  • keil5编译中出现的错误(6):FCARM - Output Name not specified, please check ‘Options for Target - Utilities‘

    在导入其他文件进入工程中会出现这个错误:FCARM - Output Name not specified, please check \\\'Options for Target - Utilities\\\' 我在网上找了好多个博主的文章,试了好几个方法,花了几个小时一直解决不了,最后才发现是导入时导入文件的格式选错了。。。 本文将列出报这个错误的两个常见情

    2024年01月24日
    浏览(36)
  • chatgpt赋能python:Python的Popen介绍及使用方法

    在Python编程中,我们经常需要执行外部命令并获取结果。而Python中的Popen函数就是一个方便的工具,可以启动另一个进程并与之交互。在本文中,我们将介绍Popen的基础知识以及使用方法。 Popen是Python的subprocess模块提供的一个函数,可以启动一个新进程并与之交互。它的基本

    2024年02月10日
    浏览(37)
  • Python3 os.makedev() 方法、Python3 os.popen() 方法

    概述 os.makedev() 方法用于以major和minor设备号组成一个原始设备号。 语法 makedev() 方法语法格式如下: 参数 major  -- Major 设备号。 minor  -- inor 设备号。 返回值 返回设备号。 实例 以下实例演示了 makedev() 方法的使用: 执行以上程序输出结果为: 概述 os.popen() 方法用于从一个

    2023年04月09日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包