【问题标题】:Handle JSON returned from Subprocess [closed]处理从子进程返回的 JSON [关闭]
【发布时间】:2021-03-27 08:21:11
【问题描述】:

我正在调用 AWS CLI:aws ec2 describe-volumes --query Volumes[*].{ID:VolumeId},它返回 json:

[
  {
    "ID": "vol-123456789101112"
  }
]

我从 python 的 subprocess 函数调用它:

command = subprocess.run('aws ec2 describe-volumes --query Volumes[*].{ID:VolumeId}', shell=True, capture_output=True)
output = command.stdout

哪些输出:b'[\r\n {\r\n "ID": "vol-123456789101112"\r\n }\r\n]\r\n'

有没有更好的方法来收集这个 json,然后在返回多个 ID 时更容易解析和收集各个 ID。

【问题讨论】:

  • 你所拥有的应该很容易解析,不是吗? json.loads(command.stdout) 不起作用吗?您在尝试时遇到的具体问题是什么?
  • 在你的代码中我唯一认为是完全糟糕的做法是使用shell=True;使用['aws', 'ec2', 'describe-volumes', '--query', 'Volumes[*].{ID:VolumeId}'] 作为您的命令会更合适,然后不必担心当前shell 是否会在查询到aws 命令的过程中破坏查询。
  • (确保即使您使用shell=True,您的数据也不会被破坏的另一种方法是在您的shell命令中使用正确的引用;"aws ec2 describe-volumes --query 'Volumes[*].{ID:VolumeId}'"是安全的,只要明确定义没有符合 POSIX 的 shell 将修改该单引号字符串的内容)。
  • 为什么不直接使用boto3呢?

标签: python json


【解决方案1】:

subprocess 在 Python 3 上默认返回 bytes。如果您需要文本,请尝试将 text=True 添加到关键字参数中。 (json 会接受 bytes 就好了,但如果你想在解析之前检查结果,你可以轻松摆脱令人不安的 b 前缀。)

command = subprocess.run(
     ['aws', 'ec2', 'describe-volumes', '--query', 'Volumes[*].{ID:VolumeId}'],
     check=True, text=True, capture_output=True)

还要注意 check=True 的添加和重构以删除不必要和浪费的 shell=True

【讨论】:

  • json.loads() 可以很好地处理字节串,所以我真的不知道 OP 想要问的问题是什么。
  • @CharlesDuffy 谢谢,就像你写的一样,添加了一条评论(-:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-13
  • 1970-01-01
  • 2011-10-25
  • 1970-01-01
相关资源
最近更新 更多