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('
'))
二、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)
最后: