subprocess模块、
一、python执行命令方法
1、os.system()
os.system()的返回值是脚本的退出状态码,0表示成功; 其他均为失败
执行命令出错,并不会影响主进程执行
res = os.system('ls')
print(res) # 0
res = os.system('dddd')
print(res) # 32512
print(os.system('ls'))
print(os.system('ddd'))
print(111)
0
32512
111
2、subprocess模块
1)subprocess包提供了三个开启子进程的方法:
subprocess.call()
subprocess.check_call()
subprocess.check_output()
2)三种方法区别在于返回结果不同:
call()
返回子进程的执行返回码check_call()
返回子进程的执行返回码的处理结果,返回码是0则返回0,否则出错的话会raise CalledProcessErrorcheck_output()
返回码是0则返回子进程向stdout输出的结果,否则也raise CalledProcessError
3)传递命令字符串作为参数,可以用以下两种形式
- 列表形式:
['ping','www.baidu.com','-c','3']
- 字符串形式:
"ping www.baidu.com -c 3"
4)在开启子进程的时候,可以加上shell=True
的参数来让python开启一个shell,通过shell来解释获得的命令。
- 一般在windows下运行的程序最好都把
shell=True
加上,这样才能顺利地执行dos命令 - 在linux下似乎不加也没啥关系。因为linux下未指明用shell执行的话会调用
/bin/sh
来执行,但是dos下系统不会默认用cmd.exe来执行命令,所以要加上shell=True。
5)这三个方法都是对subprocess.Popen
方法的一个包装,让父进程挂起等待的,在子进程结束之前,父进程不会继续往下运行。
6)subprocess.Popen()
方法不会让父进程等待其完成的, 如要父进程等待子进程,必须调用wait()
方法
二、subprocess.Popen()方法
subprocess.Popen(args, bufsize=-1, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
shell=False, cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0,
restore_signals=True, start_new_session=False,
pass_fds=(), *, encoding=None, errors=None)
"""
常用参数:
args: 字符串或列表
stdin, stdout and stderr: None->继承父进程;PIPE->创建管道; 等等
preexec_fn: (POSIX only) 在创建(fork)和执行(exec)之间执行
shell: unix相当于在args前面添加"/bin/bash -c";widows下相当于添加"cmd.exe /c"
cwd: 设置shell执行的工作目录
env: 设置环境变量
Attributes:
stdin, stdout, stderr, pid, returncode
"""
三、在一个shell中执行多条命令
方式一:
创建一个shell,通过stdin.write()
来不断执行命令
之一每个命令多要用utf-8
编码,
结尾表示模拟回车执行命令
p = subprocess.Popen("/bin/bash", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
p.stdin.write('chmod +x /data/start.sh
'.encode('utf-8'))
p.stdin.write('cd /data
'.encode('utf-8'))
p.stdin.write('./start.sh
'.encode('utf-8'))
p.stdin.close()
p.wait()
方式二:
将多条命令整合到一条中,然后执行
p = subprocess.Popen('chmod +x /data/start.sh && cd /data && ./start.sh', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.wait()