我有一个curl命令的json输出,我想得到一个值,但无法弄清楚如何做到这一点。我试图获得" X-Subject-Token"如下所示。
阅读类似的答案,我发现我可以使用json.load(sys.stdin)['X-Subject-Token']'
。我试着运行下面的代码段......
$ curl -v -s -X POST https://host.com:13000/v3/auth/tokens?nocatalog \
-H "Content-Type: application/json"
-d '{\
"auth": {\
"identity": {\
"methods": [\
"password"\
],\
"password": {\
"user": {\
"domain": {\
"name": "'"$OS_USER_DOMAIN_NAME"'"\
},\
"name": "'"$OS_USERNAME"'",\
"password": "'"$OS_PASSWORD"'"\
}\
}\
},\
"scope": {\
"project": {\
"domain": {\
"name": "'"$OS_PROJECT_DOMAIN_NAME"'"\
},\
"name": "'"admin"'"\
}\
}\
}\
}' | \
python -m json.tool | \
python -c 'import sys, json; print json.load(sys.stdin)['X-Subject-Token']'
...这给了我以下错误:
File "<string>", line 1, in <module>
KeyError: 'X-Subject-Token'
试图替换单引号的双引号......
print json.load(sys.stdin)["X-Subject-Token"]'
...得到一个不同的错误:
NameError: name 'X' is not defined.
这是我尝试从中提取的输出的片段:
> Accept: */*
> Content-Type: application/json
> Content-Length: 245
>
} [data not shown]
* upload completely sent off: 245 out of 245 bytes
< HTTP/1.1 201 Created
< X-Subject-Token: xxxxxxxxxxxxxxxxxxxxxxx
< Vary: X-Auth-Token
< Content-Type: application/json
< Content-Length: 489
我如何获得X-Subject-Token
?
我也尝试过grep和awk,我有更多的经验,但Python似乎是最干净的。
答案 0 :(得分:2)
似乎@jwodder指出的情况:X-Subject-Token
不是JSON的一部分,而是HTTP标头之一。
当您发出HTTP请求时,响应会附带一个正文和一系列标题。标头对于服务器和浏览器正常通信很重要;身体是我们通常想要的信息。由于标题通常(但并非总是)仅与服务器和浏览器相关,因此默认情况下curl
仅为我们提供正文。在这里,我将使用一些随机JSON作为示例:
$ curl -X GET https://pastebin.com/raw/S5bxekgg
{"foo": "bar", "a": 2}
身体如此相关,你甚至相信你需要的信息就在其中 - 但事实并非如此!它在标题中。在这种情况下,我们还需要curl
来为我们提供标题。这很容易,我们只需要给它-i
选项:
$ curl -i -X GET https://pastebin.com/raw/S5bxekgg
HTTP/1.1 200 OK
Date: Mon, 07 May 2018 23:12:36 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=d570bd74e5f34b1ef0d5fe4658ba5e0461525734756; expires=Tue, 07-May-19 23:12:36 GMT; path=/; domain=.pastebin.com; HttpOnly
Cache-Control: public, max-age=1801
Access-Control-Allow-Origin: *
Vary: Accept-Encoding
X-XSS-Protection: 1; mode=block
CF-Cache-Status: HIT
Expires: Mon, 07 May 2018 23:42:37 GMT
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
CF-RAY: 41775f564ca44bbd-GRU
{"foo": "bar", "a": 2}
现在我们有更多信息!唉,我的示例中没有您想要的X-Subject-Token
标题,因此我将使用另一个标题:X-XSS-Protection
。
但它不在JSON中;我们怎么得到它?好吧,它更容易:使用shell!就个人而言,我会为我想要的标题寻找:
$ curl --silent -i -X GET https://pastebin.com/raw/S5bxekgg | grep X-XSS-Protection
X-XSS-Protection: 1; mode=block
一旦我拥有它,我就会使用cut
取出值:
$ curl --silent -i -X GET https://pastebin.com/raw/S5bxekgg | grep X-XSS-Protection | cut -d: -f2
1; mode=block
它只是其中一种选择!我们甚至不需要Python!
所以,如果我的假设是正确的,问题不是Python,是你把HTTP响应头与HTTP响应体混淆了。如果你正在处理很多概念,那可能会有些混乱,但实践中无法解决;)
答案 1 :(得分:2)
X-Subject-Token是响应中的http标头。您可以使用curl的const namesHardest = ['emIly jack sMith', 'angeliNA Jolie', 'braD piTt'];
let conv=Array.from(namesHardest,a=>a.toLowerCase().replace(/\b[a-z]/g, function(letter) {
return letter.toUpperCase();
}))
console.log(conv);
标志将响应标头打印到stdout。然后你只需使用例如awk提取它。
--include