• os与subprocess模块执行系统命令


    https://docs.python.org/3/library/os.html

    https://docs.python.org/3/library/subprocess.html

    subprocess是对os.system的一个改进型模块,建议实际中使用subprocess模块内的命令来执行系统命令。关于他们之间的差别请详细阅读上述官方文档。

    一、os.system与os.popen

    1. os.system(command)

    Execute the command (a string) in a subshell. This is implemented by calling the Standard C function system(), and has the same limitations。

    On Unix, the return value is the exit status of the process encoded in the format specified for wait()

    On Windows, the return value is that returned by the system shell after running command。

    在unix和windows系统下其返回值是不一样的,unix下返回一个returncode,而非执行结果,windows下则返回执行结果。

     os.system('ls')
    

    2. os.popen(cmd, mode='r', buffering=-1)

    Open a pipe to or from command cmd. The return value is an open file object connected to the pipe, which can be read or written depending on whether modeis 'r' (default) or 'w'。

    为要执行的命令开一个pipe,返回值为此pipe(一般为一个打开的文件),mode参数即为打开模式,可以从此文件中读取返回的结果。

    popen并不会等命令执行完毕,而是会直接返回一个pipe端对象,正如上边所说的,可以使用readlines等读取已经写入的内容。

    例如:

    tmp = os.popen('ls *.py').readlines()
    # popen可以使用with上下文语法来处理:
    In [9]: with os.popen('ls') as p:
       ...:     for l in p.readlines():
       ...:         print(l.strip('
    '))
    
    popen的好处在于:将返回的结果存于临时文件中,便于程序处理。
    system()与popen()的区别则在于,前者需要等命令执行完毕才返回,后者不会等子进程执行完毕,system()就相当于popen().wait(),后者也是返回returncode。
    python3的官网已经说明了,os.popen是基于subprocess.Popen实现的:This is implemented using subprocess.Popen; 
    而在python2.7的官方文档里说明了:Deprecated since version 2.6,即此方法自2.6以来已经被放弃了。
    因此建议,使用subprocess.Popen来执行系统命令。

    二、subprocess模块

    os模块里还有很多其他重要的method,但是仅就执行系统命令来说,subprocess模块是这项功能的改进版。

    subprocess主要是run()方法和Popen()对象,前者在python3.5之前可能大多使用call(),在3.5之后使用run()来简化。

    subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)

    Run the command described by args. Wait for command to complete, then return a CompletedProcess instance.

    即run():执行指定的命令,等待执行结束并返回一个CompletedProcess 实例对象。

    import subprocess
    subprocess.call (["cmd", "arg1", "arg2"],shell=True)
    

    class 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=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None)

    Execute a child program in a new process. On POSIX, the class uses os.execvp()-like behavior to execute the child program. On Windows, the class uses the Windows CreateProcess() function.

    即Popen():开启一个子进程执行命令。

    run与Popen的差别在于,前者是一个method,会在执行完命令然后返回一个包含returncode和所执行的命令的CompletedProcess对象,后者则只是建好子进程,想要获取结果就得使用此class的各种instance method。

    在获取执行结果方面有些类似于os.system与os.popen的差别。

    而Popen class相对于os.popen的优势在于,Popen是一个构造一个class instance,popen是一个method,一个instance显然具有更多的选项,可以帮助我们更好的控制子进程。

    import subprocess
    p = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    for line in p.stdout.readlines():
        print(line)
    retval = p.wait()
    # Popen对象支持with上下文写法:
    with subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as p:
        for line in p.stdout.readlines():
            print(line)
    

    最后:

    1.当执行命令的参数或者返回中包含了中文字符,那么建议使用subprocess。
    2.综上所述,还是建议使用subprocess.Popen来执行系统命令,一方面Popen相比os.system()和subprocess.run()是非阻塞模式的,另一方面Popen相比os.popen()更加的灵活与全面,所以建议在执行操作系统命令时使用subprocess.Popen对象,并同时推荐其with写法。
  • 相关阅读:
    UVA 11198 Dancing Digits
    UVA 10085 The most distant state
    UVA 321 The New Villa
    UVA 10422 Knights in FEN
    poj2876
    poj2895
    poj2914
    poj2892
    poj2941
    LD SDK LDCControlDll 中 CXMLFile的进一步使用方法,建议以后改进
  • 原文地址:https://www.cnblogs.com/leohahah/p/12704432.html
Copyright © 2020-2023  润新知