python调用os.popen无法获取java -version版本信息,os.popen的返回对象应该是标准输出stdout,
通过调查,发现java -version的信息输出到了stderr,还纳闷获取ls信息都是正常,java就不行了。
outBuff = os.popen('java -version') outList = outBuff.readlines() print(outList)
调用系统命令或者其他程序,无外乎就两种输出,标准输出和标准错误,下面有三种方法可以解决。
1,常用的调用系统命令也有三种,通过重定向(到文件或者对象)都可以获取输出内容,阻塞执行。
重定向较麻烦,会造成输出紊乱需要恢复,比如执行 os.system('pwd')和os.popen('pwd'),
os.system返回值ret >>= 8才是程序退出值,os.popen返回的是file对象可以调用ret.readlines()
retCode = os.system('java -version') print(retCode >> 8) os.system返回一个16位的二进制数,低位为杀死所调用脚本的信号号码,高位为脚本的退出状态码
2,buf = os.popen('java -version') , buf.read()和buf.readlines()对象只能获取到stdout输出。
outBuff = os.popen('java -version') outList = outBuff.readlines() print(outList) # java -version比较奇葩,版本输出到了stderr,readlines只能获取stdout # 增加重定向可以解决此问题: outBuff = os.popen('java -version 2>&1')
3,若想同时获取stdout和stderr,可以使用subprocess.Popen()还可以交互输入,获取所有输出。
import subprocess obj = subprocess.Popen(['java', '-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) p = subprocess.Popen("java -version", shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) cmd_out = p.stdout.readlines() cmd_err = p.stderr.readlines() print('ver cmd_out=' + str(cmd_out)) print('ver cmd_err=' + str(cmd_err))
4,python标准输出输出流重定向
在Python中,文件对象sys.stdin、sys.stdout和sys.stderr分别对应解释器的标准输入、标准输出和标准出错流。 在程序启动时,这些对象的初值由sys.__stdin__、sys.__stdout__和sys.__stderr__保存, 以便用于收尾(finalization)时恢复标准流对象。 print语句不以逗号为结尾时,输出字符串尾部自动附加一个换行符;以逗号结尾时,则用代替附加一个空格 f_handler=open('out.log', 'w') sys.stdout=f_handler print 'hello' # this hello can't be viewed on concole # this hello is in file out.log sys.stdout.write('hello'+'\n') print 'hello' hi=raw_input('hello') print 'hello? ', #comma to stay in the same line hi=sys.stdin.readline()[:-1] # -1 to discard the '\n' in input stream
5,重定向同时输出到控制台和文件
import sys class __redirection__: def __init__(self): self.buff='' self.__console__=sys.stdout def write(self, output_stream): self.buff+=output_stream def to_console(self): sys.stdout=self.__console__ print self.buff def to_file(self, file_path): f=open(file_path,'w') sys.stdout=f print self.buff f.close() def flush(self): self.buff='' def reset(self): sys.stdout=self.__console__ if __name__=="__main__": # redirection r_obj=__redirection__() sys.stdout=r_obj # get output stream print 'hello' print 'there' # redirect to console r_obj.to_console() # redirect to file r_obj.to_file('out.log') # flush buffer r_obj.flush() # reset r_obj.reset()
安装python 2.7.15启用pip方法,参考doc文档Installing Python Modules章节,以及安装模块命令如下:
python -m ensurepip --default-pip pip downlaod xlrd pip install xlrd-1.1.0-py2.py3-none-any.whl