Используя Python, как я могу извлечь номер версии из вывода оболочки? - PullRequest
0 голосов
/ 09 февраля 2019

Я все еще учусь ...

Использование python Я хочу извлечь номер версии из вывода оболочки, чтобы определить, требуется ли обновление.

Я смог использовать подпроцесс.позвоните по номеру shell=true, однако я прочитал, что это проблема безопасности и хотел бы посоветовать лучший метод.Затем я нажимаю 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()

IОжидайте, что выход StrictVersion (версия) будет 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

1 Ответ

0 голосов
/ 09 февраля 2019

Непосредственная и узкая проблема заключается в том, что 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...