python使用subprocess.Popen运行bat脚本时
2017-03-27 本文已影响0人
liuzc
大图请右击在新标签页打开
Popen默认shell参数为False:
![1](http://imglf2.nosdn.127.net/img/RUJVT2hBVzdRcTRTWmpFWCszT3RUZjdleU5sOUpyVlM4bUdCMFVXbVFzNmpZU1VyeTQxVXB3PT0.png?imageView&thumbnail=1680x0&quality=96&stripmeta=0&type=jpg)
为True时默认使用 COMSPEC 环境变量指定的程序为shell:
![2](http://imglf0.nosdn.127.net/img/RUJVT2hBVzdRcTRTWmpFWCszT3RUWUw3NHRQaTBNSDZaT0R4MnNsUFpUWWNKbEo5TWphUWdBPT0.png?imageView&thumbnail=1680x0&quality=96&stripmeta=0&type=jpg)
在Windows上默认为cmd:
![3](http://imglf.nosdn.127.net/img/RUJVT2hBVzdRcTRTWmpFWCszT3RUVlF6b3oyRVpTSTlOaUFFbjBHTGJYVGYwYW4xVFVUbUx3PT0.png?imageView&thumbnail=500x0&quality=96&stripmeta=0&type=jpg)
args参数为命令字符串时,因为dir是cmd的内建命令,需要指定shell=True:
例如:
![4](http://imglf0.nosdn.127.net/img/RUJVT2hBVzdRcTRTWmpFWCszT3RUWm1GZTQxa2FmMTNEamdSL09RUW9PNXI2cUo3S0hsNVhnPT0.png?imageView&thumbnail=1680x0&quality=96&stripmeta=0&type=jpg)
而timeout,ping等都是独立的exe,可以不需要cmd:
![5](http://imglf2.nosdn.127.net/img/RUJVT2hBVzdRcTRTWmpFWCszT3RUUzZoVERUeFVSRFlZS2JUYXZYbmh2anZISlhzSlhGZmJnPT0.png?imageView&thumbnail=1680x0&quality=96&stripmeta=0&type=jpg)
args参数是文件路径形式时:
![6](http://imglf1.nosdn.127.net/img/RUJVT2hBVzdRcTRTWmpFWCszT3RUVWpiVXB6UVpuUFA4aW9NTzk5RjVmNWNtM3IwSm94WFNnPT0.png?imageView&thumbnail=1680x0&quality=96&stripmeta=0&type=jpg)
底层是调用了Windows的API,如下:
![7](http://imglf2.nosdn.127.net/img/RUJVT2hBVzdRcTRTWmpFWCszT3RUVDlzbEdIL0xMNHNKdlgvQzE2TEVlTmVYaFhDWnBXbVJ3PT0.png?imageView&thumbnail=1680x0&quality=96&stripmeta=0&type=jpg)
调试:
![8](http://imglf1.nosdn.127.net/img/RUJVT2hBVzdRcTRTWmpFWCszT3RUYWU1MjdKTGdoRHlyTjFNMnQ3WVh6elB0dFRRN0lDNEJ3PT0.png?imageView&thumbnail=1680x0&quality=96&stripmeta=0&type=jpg)
测试:
![11](http://imglf0.nosdn.127.net/img/RUJVT2hBVzdRcTRTWmpFWCszT3RUUURPRmEvZ2ZGb1gyQ0pNd1ZKZm1JY3Q4YXVkT0pmMzNRPT0.jpg?imageView&thumbnail=1680x0&quality=96&stripmeta=0&type=jpg)
从调试结果以及测试来看,对于bat文件,可以不写lpApplicationName参数,Windows会自动使用cmd来运行(使用vbs文件测试返回错误:不是正确的win32程序,要指定lpApplicationName为cscript.exe才行,可能只有bat才有这个特权了)。
输入重定向的问题:
Popen是用创建子进程的方式来执行的,而timeout.exe在暂停时,可接受用户按键来终止,这个时候会需要输入,但是Popen给子进程的stdin只有
![10](http://imglf0.nosdn.127.net/img/RUJVT2hBVzdRcTRTWmpFWCszT3RUUi9PdUZFeHZ2aVBNZUtCWEJ2ZXg4dFMzWVczR0ZLV2xBPT0.png?imageView&thumbnail=1680x0&quality=96&stripmeta=0&type=jpg)
并不能让timeout重定向到用户输入上,所以出错。
解决的方法有很多,最简单的替换掉timeout语句为ping -w xxx 127.0.0.1 或者直接由python来接管timeout。