卷曲:如何从文件中传递特定键的值

时间:2018-06-15 09:20:29

标签: bash curl

无法找到,我不确定是否可能。我知道我可以通过@ file.json传递整个有效负载,类似于

$ curl -X POST -H "Content-Type: application/json" -d @test.json \
http://localhost/api/v3/endpoint 

$ cat test.json
{
   "key1": "value1",
   "key2": "value2"
}

但现在我需要上传gpg公钥,我无法将密钥存储在test.json中。我需要的是像

$ curl -X POST -H "Content-Type: application/json" \
http://localhost/api/v3/endpoint \
-d '{"key1": "value1", "key2": "@gpg-public.key"}'

提前致谢

作为bash中的一个选项,我可以使用以下

$ curl -X POST -H "Content-Type: application/json" \
http://localhost/api/v3/endpoint \
-d "{\"key1\": \"value1\", \"key2\": \"$(cat gpg-public.key)\"}"

但我正在寻找更优雅的方式

3 个答案:

答案 0 :(得分:3)

我不能说这更优雅,但至少它是不同的。

jq -Rn '{key2: input}' <pgp-public.key |
jq -s '.[0] * .[1]' test.json - |
curl -d @- ...

jq黑客的信用:Simo Kinnunen's answer hereCharles Duffy's answer here

答案 1 :(得分:0)

使用带有-F参数的multipart / form-data,它支持一次上传多个文件。

curl -F json=@test.json -F pgp=@pgp-public.key http://localhost/api/v3/endpoint

ofc,API端点还需要支持multipart / form-data才能工作。

编辑:按照你的评论,如果发送单个json文件,然后根据需要编辑json文件并发送编辑后的版本,遗憾的是bash不适合编辑json (虽然我确定它是 possible ),但我建议使用其他一些脚本语言。这是一个用php-cli编辑json的例子,然后通过stdin将编辑好的json发送到curl:

php -r '$p=json_decode(file_get_contents("test.json"),true);$p["key2"]=file_get_contents("pgp-public.key");echo json_encode($p);' | 
curl -d @- -X POST -H "Content-Type: application/json" http://localhost/api/v3/endpoint

(但任何支持json的语言都应该足够,比如python / perl / php)

答案 2 :(得分:0)

JSON的第一条规则是使用知道JSON的工具来生成动态值。一个好工具是import UIKit class ViewController: UIViewController { var childViewController: UIViewController! override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) coordinator.animate(alongsideTransition: { (context) in self.childViewController.navigationController?.view.frame = CGRect(x: size.width / 2, y: 0, width: size.width / 2, height: size.height) }, completion: nil) } override func viewDidLoad() { super.viewDidLoad() childViewController = UIViewController() childViewController.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Test", style: .plain, target: nil, action: nil) let nav = UINavigationController(rootViewController: childViewController) addChildViewController(nav) view.addSubview(nav.view) nav.didMove(toParentViewController: self) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) let popup = UIViewController() popup.definesPresentationContext = true let nav = UINavigationController(rootViewController: popup) nav.modalPresentationStyle = .popover nav.definesPresentationContext = true nav.popoverPresentationController?.barButtonItem = childViewController.navigationItem.leftBarButtonItem childViewController.present(nav, animated: true) { print("Popup displayed") print("container: \(self)") print("child: \(self.childViewController), child.nav: \(self.childViewController.navigationController)") print("presentingViewController: \(nav.presentingViewController)") } } } 。现在,不是将JSON文件存储在磁盘上,而是存储jq过滤器,该过滤器可以充当JSON文件的模板

jq

现在,您可以使用此模板作为过滤器运行# test.jq { key1: "value1", key2: $gpg } ,并为其提供值以替换jq

$gpg

拥有此命令后,您可以使用它通过标准输入将生成的JSON直接传递给$ jq -n -f test.jq --arg gpg hi { "key1": "value1", "key2": "hi" } ; curl选项可以将-d作为参数从标准输入中读取。

@-

对于简单作业,您可以在命令行上指定过滤器,而不是从文件中读取过滤器。

jq -n -f test.q --arg gpg hi | curl ... -d @-