python в Ubuntu Linux: json.decoder.JSONDecodeError: Ожидаемое значение: строка 2, столбец 6 - PullRequest
0 голосов
/ 15 июня 2019

Я получаю ошибку ниже, когда я запускаю скрипт Python в Ubuntu 16.04.

Он отлично работает в Windows, когда я запускаю тот же код, но не уверен, какой пакет установлен неправильно.

import subprocess
import json

#one vnet and one subnet in the resourcegroup.
def get_vnet_name(resourcegroup):
    get_vnet_command=["az","network","vnet","list","--resource-group",resourcegroup]
    get_vnet=subprocess.run(get_vnet_command, shell = True, stdout=subprocess.PIPE, stderr = subprocess.PIPE)
    a=get_vnet.stdout.decode('utf-8')
    d=json.loads(a)
    for item in d:
        vname=item["name"]
        subnets=item["subnets"]
    for i in subnets:
        subnetname=i["name"]
    return vname,subnetname

def create_vm(vm_resourcegroup,vm_name, vm_image,vm_username, vm_passowrd,vm_vnet,vm_subnet, vm_size):
    create_vm_command=["az","vm","create","--resource-group",vm_resourcegroup,"--name",vm_name,"--image",vm_image, "--admin-username", vm_username,"--admin-password",vm_passowrd,"--vnet-name",vm_vnet,"--subnet",vm_subnet,"--size", vm_size]
    create_vm=subprocess.run(create_vm_command, shell = True, stdout=subprocess.PIPE, stderr = subprocess.PIPE)
    return


if __name__=="__main__":
    rscgroup_name="vm-test-group"
    avm_name="testvm1"
    avm_image="Win2019Datacenter"
    avm_username="myuser"
    avm_password="mypassword"
    avm_size="Standard_D2_V3"
    vault_name = "aqrahkeyvault"
    certificate_name = "staticwebsite"

    avm_vnet,avm_subnet=get_vnet_name(rscgroup_name)
    create_vm(rscgroup_name,avm_name,avm_image,avm_username,avm_password,avm_vnet,avm_subnet,avm_size)

Ниже приведена ошибка, которую я получаю в связи с json.decoder:

  root@linuxvm:/home/azureuser# python3.6  test2.py
    Traceback (most recent call last):
      File "test2.py", line 32, in <module>
        avm_vnet,avm_subnet=get_vnet_name(rscgroup_name)
      File "test2.py", line 9, in get_vnet_name
        d=json.loads(a)
      File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
        return _default_decoder.decode(s)
      File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
        obj, end = self.raw_decode(s, idx=_w(s, 0).end())
      File "/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
        raise JSONDecodeError("Expecting value", s, err.value) from None
    json.decoder.JSONDecodeError: Expecting value: line 2 column 6 (char 6)

Я пытался установить python, но это не помогло решить проблему.

1 Ответ

1 голос
/ 17 июня 2019

Я попытался воспроизвести вашу проблему и успешно выяснить причину.На самом деле, ваш сценарий в основном корректен, но вы можете не учитывать случай, когда команда az не возвращает никакого результата stdout.

Например, в моем списке есть несуществующая группа ресурсовподписка, например non-exist-rg.Если я передам его как значение параметра --resource-group, приведенный ниже скрипт вернет информацию об ошибке в stderr, значение stdout равно b''.

import subprocess
resourcegroup = 'non-exist-rg'
get_vnet_command=["az","network","vnet","list","--resource-group",resourcegroup]
get_vnet=subprocess.run(get_vnet_command, shell = True, stdout=subprocess.PIPE, stderr = subprocess.PIPE)

Результат stdout& stderr, как показано ниже.

>>> get_vnet.stdout
b''
>>> get_vnet.stderr
b"ERROR: Resource group 'non-exist-rg' could not be found.\r\n"

Так что, если вы передадите значение stdout в функцию json.loads, это вызовет ту же проблему, что и ваша, json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0), потому что json.loads не можетобрабатывать пустой контент.И здесь функция decode для значения bytes, равного stdout или stderr, не требуется для json.loads, который может получить значение bytes, как показано на рисунке ниже.

enter image description here

Таким образом, чтобы исправить это, нужно проверить, является ли значение stdout пустым или значение stderr не пустым.

def get_vnet_name(resourcegroup):
    get_vnet_command=["az","network","vnet","list","--resource-group",resourcegroup]
    get_vnet=subprocess.run(get_vnet_command, shell = True, stdout=subprocess.PIPE, stderr = subprocess.PIPE)
    # decode for stdout is not necessary
    # a=get_vnet.stdout.decode('utf-8')
    vname,subnetname = '', ''
    if get_vnet.stdout == b'':
        d=json.loads(get_vnet.stdout)
        for item in d:
            vname=item["name"]
            subnets=item["subnets"]
        for i in subnets:
            subnetname=i["name"]
    return vname,subnetname

Затем вам нужно проверить значения vname & subnetname, прежде чем вызывать метод create_vm.

Надеюсь, это поможет.

...