Bash script: Use string variable in curl JSON Post data

后端 未结 3 832
小蘑菇
小蘑菇 2020-11-30 10:04

I want to send a json request and embedd a variable in the post data. I did a little research and I came up with the single quotes around the variable.

    #         


        
相关标签:
3条回答
  • 2020-11-30 10:47

    My suggestion:

    #!/bin/bash
    FILENAME="/media/file 2.avi"
    curl -i -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "Player.Open", "params":{"item":{"file":"'"$FILENAME"'"}}}' http://192.167.0.13/jsonrpc
    

    The differences are hyphen in -d (instead of a dash) and double quotes around $FILENAME.

    0 讨论(0)
  • 2020-11-30 11:01

    Update: use the simpler

    request_body=$(cat <<EOF
    {
      "jsonrpc": "2.0",
      "method": "Player.Open",
      "params": {
        "item": {
          "file": "$FILENAME"
        }
      }
    }
    EOF
    )
    

    rather than what I explain below. However, if it is an option, use jq to generate the JSON instead. This ensures that the value of $FILENAME is properly quoted.

    request_body=$(jq -n --arg fname "$FILENAME" '
    {
      jsonrpc: "2.0",
      method: "Player.Open",
      params: {item: {file: $fname}}
    }'
    

    It would be simpler to define a variable with the contents of the request body first:

    #!/bin/bash
    header="Content-Type: application/json"
    FILENAME="/media/file.avi"
    request_body=$(< <(cat <<EOF
    {
      "jsonrpc": "2.0",
      "method": "Player.Open",
      "params": {
        "item": {
          "file": "$FILENAME"
        }
      }
    }
    EOF
    ))
    curl -i -X POST -H "$header" -d "$request_body" http://192.167.0.13/jsonrpc
    

    This definition might require an explanation to understand, but note two big benefits:

    1. You eliminate a level of quoting
    2. You can easily format the text for readability.

    First, you have a simple command substitution that reads from a file:

    $( < ... )   # bash improvement over $( cat ... )
    

    Instead of a file name, though, you specify a process substitution, in which the output of a command is used as if it were the body of a file.

    The command in the process substitution is simply cat, which reads from a here document. It is the here document that contains your request body.

    0 讨论(0)
  • 2020-11-30 11:01

    Here is another way to insert data from a file into a JSON property. This solution is based on a really cool command called jq.

    Below is an example which prepares request JSON data, used to create a CoreOS droplet on Digital Ocean:

    # Load the cloud config to variable
    user_data=$(cat config/cloud-config)
    
    # Prepare the request data 
    request_data='{
      "name": "server name",
      "region": "fra1",
      "size": "512mb",
      "image": "coreos-stable",
      "backups": false,
      "ipv6": true,
      "user_data": "---this content will be replaced---",
      "ssh_keys": [1234, 2345]
    }'
    
    # Insert data from file into the user_data property
    request_data=$(echo $request_data | jq ". + {user_data: \"$user_data\"}")
    
    0 讨论(0)
提交回复
热议问题