Python中的subprocess

看python的document 自个慢慢琢磨~~,每天花一点时间学习。某某人说要厚积薄发!

先看看subprocess是干什么用的:
The subprocess modul allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes.

即启用另一个线程,并可获取输入,输出以及错误信息等

先看两个函数:
subprocess.call(*popenargs, **kwargs)

    Run command with arguments. Wait for command to complete, then return the returncode attribute


subprocess.check_call(*popenargs, **kwargs)

    Run command with arguments. Wait for command to complete. If the exit code was zero then return, otherwise raise CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute.

>>>
>>> print subprocess.check_call(["mspaint"])
0
>>>
>>> print subprocess.call(["mspaint"])
0

我觉得两者的区别在于遇到错误的时候处理不一样,一个在返回return code ,一个会抛出异常。check_call实际上会调用call函数,然后加入了异常处理的情况。两者在本质上都会调用Popen(*popenargs, **kwargs).wait()。

Popen. wait ( )  Wait for child process to terminate. Set and return returncode attribute.
好像第一次研究python的lib包中的源码,收获还是不错的。比在网上搜索听别人说强多了。以后看来要经常这样。

>>> print subprocess.call(["mspain"])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:/Python27/lib/subprocess.py", line 486, in call
    return Popen(*popenargs, **kwargs).wait()
  File "C:/Python27/lib/subprocess.py", line 672, in __init__
    errread, errwrite)
  File "C:/Python27/lib/subprocess.py", line 882, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
>>>
>>>
>>>
>>>
>>> print subprocess.check_call(["mspain"])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:/Python27/lib/subprocess.py", line 499, in check_call
    retcode = call(*popenargs, **kwargs)
  File "C:/Python27/lib/subprocess.py", line 486, in call
    return Popen(*popenargs, **kwargs).wait()
  File "C:/Python27/lib/subprocess.py", line 672, in __init__
    errread, errwrite)
  File "C:/Python27/lib/subprocess.py", line 882, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
>>>

顺便查看了下源码:

def call(*popenargs, **kwargs):
    """Run command with arguments.  Wait for command to complete, then
    return the returncode attribute.

    The arguments are the same as for the Popen constructor.  Example:

    retcode = call(["ls", "-l"])
    """
    return Popen(*popenargs, **kwargs).wait()


def check_call(*popenargs, **kwargs):
    """Run command with arguments.  Wait for command to complete.  If
    the exit code was zero then return, otherwise raise
    CalledProcessError.  The CalledProcessError object will have the
    return code in the returncode attribute.

    The arguments are the same as for the Popen constructor.  Example:

    check_call(["ls", "-l"])
    """
    retcode = call(*popenargs, **kwargs)
    if retcode:
        cmd = kwargs.get("args")
        if cmd is None:
            cmd = popenargs[0]
        raise CalledProcessError(retcode, cmd)
    return 0

关于subprocess的安全性:

不像其他的popen函数,不会直接调用/bin/sh来解释命令,也就是说,命令中的每一个字符都会被安全地传递到子进程里。

 

Popen是subprocess中定义的类:

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 )

Arguments are:

args should be a string, or a sequence of program arguments. The program to execute is normally the first item in the args sequence or the string if a string is given, but can be explicitly set by using the executable argument. When executable is given, the first item in the args sequence is still treated by most programs as the command name, which can then be different from the actual executable name. On Unix, it becomes the display name for the executing program in utilities such as ps .

subprocess . PIPE

Special value that can be used as the stdin , stdout or stderr argument to Popen and indicates that a pipe to the standard stream should be opened.
          subprocess . STDOUT
Special value that can be used as the stderr argument to Popen and indicates that standard error should go into the same handle as standard output.

Poen的方法这段属于引用,自个难得翻译了,刚好又有现成的。明白函数咋回事即可。

Popen的方法:

Popen.poll()
用于检查子进程是否已经结束。设置并返回returncode属性。

Popen.wait()
等待子进程结束。设置并返回returncode属性。

Popen.communicate(input=None)
与子进程进行交互。向stdin发送数据,或从stdout和stderr中读取数据。可选参数input指定发送到子进程的参数。 Communicate()返回一个元组:(stdoutdata, stderrdata)。注意:如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE。同样,如 果希望从stdout和stderr获取数据,必须将stdout和stderr设置为PIPE。

Popen.send_signal(signal)
向子进程发送信号。

Popen.terminate()
停止(stop)子进程。在windows平台下,该方法将调用Windows API TerminateProcess()来结束子进程。

Popen.kill()
杀死子进程。

Popen.stdin
如果在创建Popen对象是,参数stdin被设置为PIPE,Popen.stdin将返回一个文件对象用于策子进程发送指令。否则返回None。

Popen.stdout
如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令。否则返回 None。

Popen.stderr
如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令。否则返回 None。

Popen.pid
获取子进程的进程ID。

Popen.returncode
获取进程的返回值。如果进程还没有结束,返回None。

 

关于一些替换:

  1. 与反引号执行程序替换:
    ==>
    output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0]
    output=`mycmd myarg`
  2. 替换shell 管道:
    output=`dmesg | grep hda`
    ==>
    p1 = Popen(["dmesg"], stdout=PIPE)
    p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
    output = p2.communicate()[0]
  3. 替换os.system:
    sts = os.system("mycmd" + " myarg")
    ==>
    p = Popen("mycmd" + " myarg", shell=True)
    sts = os.waitpid(p.pid, 0)[1]
>>> sts=subprocess.Popen("mstsc"+"/v:9.37.119.17",shell=True)
>>> print os.system("mstsc"+"/v:9.37.119.17")
0
>>> print subprocess.Popen("mstsc"+"/v:9.37.119.17",shell=True)
<subprocess.Popen object at 0x00BA54B0>

要获取进程执行成功与否需要使用:os.waitpid(p.pid, 0)[1]

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

惹不起的程咬金

来都来了,不赏点银子么

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值