zoukankan      html  css  js  c++  java
  • Python线程通信

    subprocess

    作用

    模块用于生产新的进程,连接到其输入、输出、错误管道,并获取其返回值

    1. 如何使用subprocess模块

    启动子进程的推荐方法是使用以下方便功能。 对于更高级的用例,当这些不满足您的需要时,使用底层的Popen interface

    • subprocess.call(args*stdin=Nonestdout=Nonestderr=Noneshell=False)

    作用:调用如args所示的系统命令,等待命令完成,返回returncode

    Example:

    >>> subprocess.call(["ls", "-l"])
    0
    
    >>> subprocess.call("exit 1", shell=True)
    1

    警告:使用shell = True可能是一个安全隐患。

    注意:不要使用stdout = PIPE或stderr = PIPE,因为它可能发生子进程输出的死锁。 当需要管道时,使用popen与communicate()方法

    • subprocess.check_call(args*stdin=Nonestdout=Nonestderr=Noneshell=False)

    运行带参数的命令。 等待命令完成。 如果返回码为零,那么返回,否则抛出CalledProcessError。 CalledProcessError对象将在returncode属性中具有返回码

    Example:

    >>> subprocess.check_call(["ls", "-l"])
    0
    
    >>> subprocess.check_call("exit 1", shell=True)
    Traceback (most recent call last):
       ...
    subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
    
    • subprocess.check_output(args*stdin=Nonestderr=Noneshell=Falseuniversal_newlines=False)

    运行系统命令,并将输出返回给一个字节字符串,如果返回值不为0,则抛出CalledProcessError异常。

    Example:

    >>> subprocess.check_output(["echo", "Hello World!"])
    'Hello World!
    '
    
    >>> subprocess.check_output("exit 1", shell=True)
    Traceback (most recent call last):
       ...
    subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
    

      想要捕获错误信息,使用stderr=subprocess.STDOUT:

    >>> subprocess.check_output(
    ...     "ls non_existent_file; exit 0",
    ...     stderr=subprocess.STDOUT,
    ...     shell=True)
    'ls: non_existent_file: No such file or directory
    '
    
    • subprocess.PIPE

    特殊值,可以用作popen的stdin,stdout或stderr参数,并指示应打开标准流的管道。

    • subprocess.STDOUT

    可以用作Popen的stderr参数的特殊值,表示标准错误应该作为标准输出进入相同的句柄。

    • 为了支持各种各样的用例,Popen构造函数(和方便函数)接受大量的可选参数。对于大多数典型的用例,许多这些参数可以安全地保留其默认值。最常需要的参数是:

      args是所有调用所必需的,应该是一个字符串或一系列程序参数。提供参数序列通常是优选的,因为它允许模块处理任何所需的转义和引用参数(例如,以允许文件名中的空格)。如果传递单个字符串,则shell必须为True(见下文),否则字符串必须简单地命名要执行的程序,而不指定任何参数。

      stdin,stdout和stderr分别指定执行程序的标准输入,标准输出和标准错误文件句柄。有效值为PIPE,现有文件描述符(正整数),现有文件对象和无。 PIPE表示应该创建一个新的管道给孩子。使用默认设置None,不会发生重定向;子进程的文件句柄将从父进程继承。此外,stderr可以是STDOUT,它指示来自子进程的stderr数据应该捕获到与stdout相同的文件句柄中。

      当stdout或stderr是管道,universal_newlines为True时,所有行尾都将转换为' n',如open()的通用换行符'U'模式参数所述。

      如果shell为True,指定的命令将通过shell执行。如果你使用Python主要用于增强的控制流,它提供了大多数系统shell,并仍然想要方便地访问其他shell功能,如shell管道,文件名通配符,环境变量扩展和扩展〜到用户的家

    使用了shell=True这个参数。这个时候,我们使用一整个字符串,而不是一个表来运行子进程。Python将先运行一个shell,再用这个shell来解释这整个字符串。

    Example:

    import subprocess
    out = subprocess.call("ls -l", shell=True)
    out = subprocess.call("cd ..", shell=True)
    • Popen 构造器
    • 此模块中的基础过程创建和管理由Popen类处理。它提供了很多灵活性,以便开发人员能够处理方便功能未涵盖的较不常见的情况。

      class subprocess.Popen(args,bufsize = 0,executable = None,stdin = None,stdout = None,stderr = None,preexec_fn = None,close_fds = False,shell = False,cwd = None,env = None,universal_newlines = False ,startupinfo = None,creationflags = 0)
      在新进程中执行子程序。在Unix上,类使用os.execvp() - 类行为来执行子程序。在Windows上,类使用Windows CreateProcess()函数。 Popen的参数如下。

      args应该是一个程序参数序列或者一个单个字符串。默认情况下,如果args是一个序列,则要执行的程序是args中的第一个项目。如果args是字符串,解释是平台相关的,如下所述。有关与默认行为的其他差异,请参阅shell和可执行参数。除非另有说明,建议将args作为序列传递。

    • Example:
    • >>> import shlex, subprocess
      >>> command_line = raw_input()
      /bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
      >>> args = shlex.split(command_line)
      >>> print args
      ['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
      >>> p = subprocess.Popen(args) # Success!
      
    • shell参数(默认为False)指定是否使用shell作为程序执行。 如果shell为True,则建议将args作为字符串而不是序列传递。

      在Unix上,shell = True,shell默认为/ bin / sh。 如果args是字符串,则该字符串指定要通过shell执行的命令。 这意味着字符串的格式必须与在shell提示符下键入时的格式完全一致。 这包括,例如,引用或反斜杠转义文件名中带有空格。 如果args是序列,则第一个项指定命令字符串,任何其他项将被视为shell本身的附加参数。 也就是说,Popen相当于:

    • Popen(['/bin/sh', '-c', args[0], args[1], ...])
    • 在shell = true的Windows上,COMSPEC环境变量指定默认shell。 只有当你需要在Windows上指定shell = True的时候,你希望执行的命令是内置在shell中(例如dir或copy)。 您不需要shell = True来运行批处理文件或基于控制台的可执行文件。
    • bufsize(如果给定)与内置open()函数的相应参数意义相同:0表示无缓冲,1表示行缓冲,任何其他正值表示使用大小为(大约)的缓冲区。 负bufsize意味着使用系统默认值,这通常意味着完全缓冲。 bufsize的默认值为0(未缓冲)。
    • 如果遇到性能问题,尝试通过将bufsize设置为-1或足够大的正值(例如4096)来启用缓冲。
    • 如果preexec_fn设置为可调用对象,则该对象将在子进程中在子进程执行之前被调用。 (仅限Unix)

      如果close_fds为true,除了0,1和2之外的所有文件描述符将在子进程执行之前关闭。 (仅限Unix)。 或者,在Windows上,如果close_fds为true,则子进程将不继承任何句柄。 请注意,在Windows上,您不能将close_fds设置为true,也可以通过设置stdin,stdout或stderr重定向标准句柄。

      如果cwd不是None,子进程的当前目录在执行之前将被更改为cwd。 注意,在搜索可执行文件时不考虑此目录,因此您不能指定程序相对于cwd的路径。

      如果env不是None,它必须是定义新进程的环境变量的映射; 这些是使用而不是继承当前进程的环境,这是默认行为。

    • 注意如果指定,env必须提供程序执行所需的任何变量。 在Windows上,为了运行side-by-side程序集,指定的env必须包含一个有效的SystemRoot。
      如果universal_newlines为True,文件对象stdout和stderr在通用换行模式下作为文本文件打开。 行可以由' n',Unix行尾约定,' r',旧的Macintosh约定或' r n'(Windows约定)中的任何一个终止。 所有这些外部表示被Python程序看作' n'。

    • Exception
      • 如果在新程序开始执行之前,在子进程中引发的异常,将在父进程中重新生成。 此外,异常对象将有一个额外的属性称为child_traceback,这是一个字符串,包含从孩子的角度的追溯信息。

        最常见的异常是OSError。 例如,当尝试执行不存在的文件时,会发生这种情况。 应用程序应准备OSError异常。

        如果使用无效参数调用Popen,将引发ValueError。

        如果被调用的进程返回非零返回码,check_call()和check_output()将引发CalledProcessError。

    • Security
      • 与其他popen函数不同,这个实现不会隐式地调用系统shell。 这意味着所有字符,包括shell元字符,都可以安全地传递给子进程。 显然,如果shell被显式地调用,则应用程序有责任确保所有空格和元字符被适当地引用。

    Popen对象

    • import subprocess
      child = subprocess.Popen(["ping","-c","5","www.google.com"])
      child.wait()
      print("parent process")

      此外,你还可以在父进程中对子进程进行其它操作,比如我们上面例子中的child对象:

      child.poll()           # 检查子进程状态

      child.kill()           # 终止子进程

      child.send_signal()    # 向子进程发送信号

      child.terminate()      # 终止子进程

     

    Popen.poll()

    Popen.wait()

    • Popen.communicate(input = None)

    与进程交互:将数据发送到stdin。 从stdout和stderr读取数据,直到达到文件结束。 等待进程终止。 可选输入参数应为要发送到子进程的字符串,如果没有数据应发送到子进程,则为None。

    communicate()返回一个元组(stdoutdata,stderrdata)。

    注意,如果你想发送数据到进程的stdin,你需要使用stdin = PIPE来创建Popen对象。 类似地,要在结果元组中获取除了None之外的任何值,您需要同时给予stdout = PIPE和/或stderr = PIPE。

    Popen.stdin
    如果stdin参数是PIPE,则此属性是向子进程提供输入的文件对象。 否则,它为无。

    Popen.stdout
    如果stdout参数是PIPE,则此属性是提供子进程输出的文件对象。 否则,它为无。

    Popen.stderr
    如果stderr参数是PIPE,则此属性是一个文件对象,它提供子进程的错误输出。 否则,它为无。

    Popen.pid
    子进程的进程ID。

    请注意,如果将shell参数设置为True,那么这是生成的shell的进程ID。

    Popen.returncode
    子返回码,由poll()和wait()设置(间接通过communic())。 无值表示进程尚未终止。

    负值-N表示子节点由信号N(仅限Unix)终止。

  • 相关阅读:
    以多维数组的形式访问动态内存 笔记
    SQL对于 小数处理的小结
    备忘,搞不明白这是为什么
    生成3位的序列号_仅仅CASE WHEN的简单应用
    DataGridView导出数据到Excel
    Sql更新
    delphi使用RichView控件 表格保存和复制
    delphi使用RichView控件 表中选择
    delphi使用RichView控件 表格单元格合并
    delphi使用RichView控件 表格大小
  • 原文地址:https://www.cnblogs.com/lebronzhang/p/6247099.html
Copyright © 2011-2022 走看看