我还在学习...
使用python,我想从shell输出中提取版本号,以确定是否需要升级。
我能够与shell=true
一起使用subprocess.call,但是我读到这是一个安全问题,希望就更好的方法提供一些建议。然后我碰到了AttributeError
,好像StrictVersion
看不到输出是整数,我认为吗?
这是我目前正在做的事情。
import subprocess
from distutils.version import StrictVersion
def updateAnsible():
print 'Checking Ansible version'
version = subprocess.call("ansible --version | grep 'ansible [0-9].[0-9].[0-9]' | awk '{ print $2 }'", shell=True)
print version
if StrictVersion(version) < StrictVersion('2.7.0'):
print "Need to upgrade"
else:
print "Do not need to upgrade"
if __name__ == '__main__':
updateAnsible()
我希望StrictVersion(version)的输出为1.2.3
但是我得到的是下面的
Checking Ansible version
1.2.3
Traceback (most recent call last):
0
File "test.py", line 32, in <module>
updateAnsible()
File "test.py", line 26, in updateAnsible
if StrictVersion(version) < StrictVersion('2.6.0'):
File "python2.7/distutils/version.py", line 140, in __cmp__
compare = cmp(self.version, other.version)
AttributeError: StrictVersion instance has no attribute 'version'
Process finished with exit code 1
答案 0 :(得分:1)
当前紧迫的问题是subprocess.call()
返回退出状态(如果0
没有失败,则返回grep
,如果失败,则返回1
),不输出。可以使用check_output()
来解决此问题:
version = subprocess.check_output(
"ansible --version | awk '/ansible [0-9].[0-9].[0-9]/ { print $2; exit }'", shell=True
).strip().decode('utf-8')
如果您想避免使用shell=True
(在当前用例中值得称赞,但实际上不是紧急的安全问题),则可能看起来像这样:
import re
av = subprocess.check_output(['ansible', '--version'])
match = re.match('^ansible (\d+[.]\d+[.]\d+)$', av.split(b'\n')[0].decode('utf-8'))
if match is None:
raise Exception("Unable to get version number from ansible")
version = match.group(1)