因为开发需求,需要通过python调用系统命令
下面是几种不同的python调用系统命令的方法
https://zhuanlan.zhihu.com/p/329957363
调用系统命令,主要关注两个指标
1.速度是否够快
2.运行结果是否准确
经过测试,实际几种方法的运行速度差不多,同时也都比直接在命令行里直接运行命令要慢,不过有一点需要注意,就是这些python调用系统命令,实际的结果是先储存在PIPE中,如果没有调用回调或者回显函数获取运行结果的话,实际运行会很快,但并不表示命令执行完了
比如
subprocess.Popen(shellstr)
或者
os.popen(shellstr)
这两行代码运行的速度都很快,实际命令shellstr也送去命令行执行了,但实际是相当于开了一个进程在后台跑,并不是运行过了python代码这行就表示shellstr命令执行完毕了。如果需要确保命令执行完后再进行下一步,需要加上相应的回调函数,去检查PIPE里的内容,这样才是python代码执行完后系统命令也执行完了
比如
subprocess.Popen(shellstr).communicate()
或者
os.popen(shellstr).read()
这样能确保系统命令完毕后才执行之后的代码,同样如果是不需要对回显进行处理或者是执行的命令不会影响之后的操作,那么则可以不检查PIPE以便加快代码运行
这里附上部分代码:
使用fp.poll来判断代码运行状态,fp.poll为None表示代码正在运行,0表示运行完成,1表示运行出错
cmd = shlex.split(shell_str)
with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as fp:
try:
line_num = 0
pipe_line = fp.stdout.readline()
cmd_status = fp.poll()
while pipe_line or cmd_status is None:
try:
line_str = pipe_line.decode('utf-8')
except UnicodeDecodeError:
# UrlEncodedFormEntity编码格式默认是iso_8859_1制
line_str = pipe_line.decode('iso_8859_1', errors="ignore")
if line_num > 500000 and line_str == ' },\n':
self.json_str.write("}]")
self.parse_msg.append("MSG\t1\t" + self.parse_status['1'] + "\texceed limit 500000 lines")
break
self.json_str.write(line_str)
line_num += 1
pipe_line = fp.stdout.readline()
cmd_status = fp.poll()