I am still learning...
Using python I want to extract the version number from a shell output to determine if an upgrade is required.
I was able to use subprocess.call with shell=true, however i read this is a security issue and would like some advise on a better method. I then hit an AttributeError as it seems StrictVersion doesn't see the output as a integer, I think?
Here is what I am doing currently.
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()
I Expect the output of StrictVersion(version) to be 1.2.3
but what i get is the below
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
shell=True. Well, no big ones; if the shell has startup-time vulnerabilities like shellshock was you'd still be in trouble, but it's not nearly as bad as mostshell=Trueuses are.StrictVersioncan parse. The output is just being written bygrepstraight to the stdout it inherited when your script was started up.subprocess.check_outputinstead ofsubprocess.callto fix the AttributeError.[0-9].[0-9].[0-9], the.s aren't matched only against the period character -- they're wildcards in regex and match any character. And since it's common for a version number to be something like2.14.3, assuming each segment will only be one digit isn't necessarily well-founded. (For that matter,2.1.3rc5is possible too, so you can't even assume digits-only if you want to be robust).