慕工程0101907
2021-11-02 20:21:24
我仍然在學習...使用 python 我想從 shell 輸出中提取版本號以確定是否需要升級。我能夠將 subprocess.call 與 一起使用shell=true,但是我讀到這是一個安全問題,并且想要一些關于更好方法的建議。然后我打了一個,AttributeError因為它似乎StrictVersion沒有將輸出視為整數,我想?以下是我目前正在做的事情。import subprocessfrom distutils.version import StrictVersiondef 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 version1.2.3Traceback (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
1 回答

紅糖糍粑
TA貢獻1815條經驗 獲得超6個贊
直接和狹隘的問題是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)
添加回答
舉報
0/150
提交
取消