ubuntu linux上的python:json.decoder.JSONDecodeError:期望值:第2行第6列

Posted

技术标签:

【中文标题】ubuntu linux上的python:json.decoder.JSONDecodeError:期望值:第2行第6列【英文标题】:python on ubuntu linux : json.decoder.JSONDecodeError: Expecting value: line 2 column 6 【发布时间】:2019-06-15 07:39:45 【问题描述】:

当我在 Ubuntu 16.04 上运行 python 脚本时出现以下错误。

当我运行相同的代码但不确定哪个包没有正确安装时,它在 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 并没有解决问题。

【问题讨论】:

你是否安装了所有必要的模块(你显然没有安装 apt_pkg)?你为什么使用 az cli 而不是 Azure Python SDK?您在运行此“代码”之前是否对 cli 进行了身份验证?什么都没有返回,因为您很可能需要进行身份验证 您在上层代码 sn-p 中暴露了您的凭据(用户和密码)。确保删除它们! 感谢 mc51 我忘了删除它。嗨 Gleb,我在使用 az login 运行 cmd 之前验证了 azure cli。然后运行python脚本。我安装了两次apt_pkg。不确定它是否仍然给我同样的错误我也需要运行 cli 代码,因为我团队中的大多数工程师都熟悉 azure cli。并且还用 azure cli 和 python 为他们工作 【参考方案1】:

我尝试重现您的问题并成功找出原因。其实你的脚本基本上是正确的,但是你可能不会考虑az命令没有返回任何结果给stdout的情况。

例如,我的订阅中有一个不存在的资源组,例如non-exist-rg。如果我把它作为参数--resource-group的值传递,下面的脚本会返回错误信息给stderrstdout的值是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 无法处理空内容。并且在这里,bytes 的值stdoutstderrdecode 函数对于json.loads 不是必需的,可以接收到bytes 的值,如下图。

所以要解决这个问题,解决方法是检查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

然后,您需要在调用create_vm 方法之前检查vnamesubnetname 的值。

希望对你有帮助。

【讨论】:

感谢 peter 进行回归测试,我还通过删除 shell = True 解决了同样的问题,我不确定 shell = true 有什么问题,但在 Linux 上它会产生问题。再次感谢。我将此标记为答案。

以上是关于ubuntu linux上的python:json.decoder.JSONDecodeError:期望值:第2行第6列的主要内容,如果未能解决你的问题,请参考以下文章

Json String Parsing 在从 MSDOS 运行时有效,但在 Windows 上的 Ubuntu 上的 Bash 中无效 [重复]

从本地机器上的 ubuntu (AWS EC2) 读取文件?

Windows 10 和 Linux Ubuntu 16.04 在运行时间上的巨大差异,用于 ExtraTreesClassifier 训练和预测 (Python)

Pip 不适用于 Ubuntu 上的 Python 3.10

安装在Ubuntu上的Python虚拟环境

Linux 上的 Python Wheels(如何?为啥?)