可以执行shell命令的相关模块和函数有:
- os.system
- os.spawn*
- os.popen* --废弃
- popen2.* --废弃
- commands.* --废弃,3.x中被移除
以上执行shell命令的相关的模块和函数的功能均在 subprocess 模块中实现,并提供了更丰富的功能
call
父进程等待子进程完成
返回退出信息(returncode,相当于Linux exit code)
执行命令,返回状态码,shell=True是表示命令可以字符串
>>> import subprocess >>> ret=subprocess.call(["ls","-l"],shell=False) total 4 -rw-r--r--. 1 root root 260 Feb 23 20:44 scrapy.cfg drwxr-xr-x. 4 root root 156 Feb 25 20:05 sokindle >>> ret=subprocess.call("ls -l",shell=True) total 4 -rw-r--r--. 1 root root 260 Feb 23 20:44 scrapy.cfg drwxr-xr-x. 4 root root 156 Feb 25 20:05 sokindle
check_call
父进程等待子进程完成
返回0
检查退出信息,如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性,可用try…except…来检查
shell默认为False,在Linux下,shell=False时, Popen调用os.execvp()执行args指定的程序;shell=True时,如果args是字符串,Popen直接调用系统的Shell来执行args指定的程序,如果args是一个序列,则args的第一项是定义程序命令字符串,其它项是调用系统Shell时的附加参数。
>>> ret=subprocess.check_call(["ls","-l"]) total 4 -rw-r--r--. 1 root root 260 Feb 23 20:44 scrapy.cfg drwxr-xr-x. 4 root root 156 Feb 25 20:05 sokindle >>> print(ret) 0 >>> subprocess.check_call("exit 1",shell=True) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/opt/python36/lib/python3.6/subprocess.py", line 291, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1. >>> subprocess.call("exit 1",shell=True) 1 >>>
check_output,类似check_call
执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常
subprocess.Popen(...)
用于执行复杂的系统命令
参数:
- args:shell命令,可以是字符串或者序列类型(如:list,元组)
- bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
- stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
- preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
- close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。 - shell:同上
- cwd:用于设置子进程的当前目录
- env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
- universal_newlines:不同系统的换行符不同,True -> 同意使用
- startupinfo与createionflags只在windows下有效
将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等
>>> import subprocess >>> subprocess.Popen(["mkdir","t1"]) <subprocess.Popen object at 0x7f7419f0fac8> >>> ret1=subprocess.Popen(["mkdir","t1"]) >>> mkdir: cannot create directory ‘t1’: File exists >>> ret2=subprocess.Popen("mkdir t2",shell=True) >>> ret2=subprocess.Popen("ls -l",shell=True) >>> total 4 -rw-r--r--. 1 root root 260 Feb 23 20:44 scrapy.cfg drwxr-xr-x. 4 root root 156 Feb 25 20:05 sokindle drwxr-xr-x. 2 root root 6 May 25 21:29 t1 drwxr-xr-x. 2 root root 6 May 25 21:30 t2
>>> obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/',) >>> obj = subprocess.Popen("ls -l",shell=True,cwd='/home',) >>> total 23464 drwxr-xr-x. 5 root root 59 Mar 5 17:18 crawl drwxr-xr-x. 3 root root 38 Feb 19 11:40 douban drwxr-xr-x. 3 root root 39 Mar 1 20:52 douban2 drwxr-xr-x. 5 root root 159 Aug 17 2016 features drwxr-xr-x. 3 root root 18 Feb 25 19:52 images drwx------. 14 lx lx 4096 Mar 2 20:59 lx drwxr-xr-x. 22 root root 4096 Aug 17 2016 plugins -rw-r--r--. 1 root root 24015561 Mar 7 20:53 PyDev_5.2.0.zip drwxr-xr-x. 4 root root 78 May 13 21:52 python drwxr-xr-x. 2 root root 6 Feb 16 20:22 python36 drwxr-xr-x. 5 root root 60 May 25 21:30 sokindle drwxr-xr-x. 2 root root 6 May 25 21:36 t3 drwxr-xr-x. 3 root root 122 Feb 17 21:13 tutorial
如果要把结果输出到屏幕需要用subprocess.PIPE
例:
ret=subprocess.Popen("ls -l",stdout=subprocess.PIPE,shell=True)
ret.stout.read()
上面正确
如果是这样
ret=subprocess.Popen("ls -l",shell=True)
ret.stout.read()没有read函数
结果--》pipe管道--》stdout
read stdout读取pipe管道
每调用subprocess就开启一新的shell进程
检查程序是否执行完或者卡住
比如:res=subprocess.Popen("sleep 10;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
如果没有执行完调用 res.stdout.read()返回的为b''
res.poll()还回None没有执行完,为0执行完
res.wait()等执行完,返回结果
res.terminate()杀死shell
import subprocess ret=subprocess.Popen("python",shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) ret.stdin.write(b"print('11') ") ret.stdin.write(b"print(222) ") ret.stdin.write(b"print(333) ") ret.stdin.write(b"print(444) ") ret.stdin.close() out=ret.stdout.read() ret.stdout.close() err=ret.stderr.read() print(out.decode("utf-8")) print(err) """ 结果 11 222 333 444 b'' """