Bash 带有 cURL 的脚本;不发送 POST 作为 JSON

Bash script with cURL; not sending POST as JSON

我正在为 运行 cURL POST 命令创建一个简单的 bash 脚本。 该脚本即使是相同的命令也不会将 POST 数据发送为 json.

当我手动输入命令时,它会毫无问题地将 POST 数据发送为 JSON。

$ curl --include --header 'Accept:application/json' --header 'Authorization:Basic xxxxxxxxxxxxxxxxx' --data '{"sourceTemplateId":111111111111111}' --header 'Content-Type:application/json' https://api.everbridge.net/rest/notifications/000000000000000
HTTP/1.1 200 OK
Server: nginx/1.8.0
Date: Wed, 18 May 2016 18:13:15 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive

{
  "message" : "OK",
  "id" : 5748251085623370,
  "baseUri" : "https://api.everbridge.net/rest/notifications/000000000000000/",
  "instanceUri" : "https://api.everbridge.net/rest/notifications/000000000000000/5748251085623370"
}

当我 运行 回显我的 bash 脚本时,我明白了。

$ ./Send_Not.sh
curl --include --header 'Accept:application/json' --header 'Authorization:Basic xxxxxxxxxxxxxxxxx' --data '{"sourceTemplateId":111111111111111}' --header 'Content-Type:application/json' https://api.everbridge.net/rest/notifications/000000000000000

完全一样的格式

但是当我 运行 脚本时,我得到这个错误。

$ ./Send_Not.sh
HTTP/1.1 415 Unsupported Media Type
Server: nginx/1.8.0
Date: Wed, 18 May 2016 18:28:50 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive

{
  "status" : 415,
  "message" : "Content type 'application/x-www-form-urlencoded' not supported"

这是我的脚本,超级简单。

#!/bin/bash
ajson=\'Accept:application/json\'
credentials=\'Authorization:Basic\ xxxxxxxxxxxxxxxxx\'
data=\'{\"sourceTemplateId\":111111111111111}\'
CT=\'Content-Type:application/json\'
url="https://api.everbridge.net/rest/notifications/000000000000000"

curl --include --header "$ajson" --header "$credentials" --data "$data" --header "$CT" "$url"

使用 -X POST 和 -v

重新运行命令
$ ./Send_Not.sh
Note: Unnecessary use of -X or --request, POST is already inferred.
* STATE: INIT => CONNECT handle 0x600057830; line 1108 (connection #-5000)
* Added connection 0. The cache now contains 1 members
*   Trying 54.193.84.167...
* STATE: CONNECT => WAITCONNECT handle 0x600057830; line 1161 (connection #0)
* Connected to api.everbridge.net (54.193.84.167) port 443 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x600057830; line 1260 (connection #0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* STATE: SENDPROTOCONNECT => PROTOCONNECT handle 0x600057830; line 1274 (connection #0)
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: C=US; ST=California; L=Glendale; O=Everbridge; OU=SaaS Operations; CN=*.everbridge.net
*  start date: Sep 18 00:00:00 2015 GMT
*  expire date: Sep 17 23:59:59 2018 GMT
*  subjectAltName: host "api.everbridge.net" matched cert's "*.everbridge.net"
*  issuer: C=US; O=GeoTrust Inc.; CN=GeoTrust SSL CA - G3
*  SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x600057830; line 1295 (connection #0)
> POST /rest/notifications/000000000000000 HTTP/1.1
> Host: api.everbridge.net
> User-Agent: curl/7.48.0
> Accept: */*
> 'Accept:application/json'
> 'Authorization:Basic xxxxxxxxxxxxxxxxx'
> 'Content-Type:application/json'
> Content-Length: 39
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 39 out of 39 bytes
* STATE: DO => DO_DONE handle 0x600057830; line 1357 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x600057830; line 1484 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x600057830; line 1494 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 415 Unsupported Media Type
HTTP/1.1 415 Unsupported Media Type
* Server nginx/1.8.0 is not blacklisted
< Server: nginx/1.8.0
Server: nginx/1.8.0
< Date: Wed, 18 May 2016 21:08:12 GMT
Date: Wed, 18 May 2016 21:08:12 GMT
< Content-Type: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Connection: keep-alive
Connection: keep-alive

<
{
  "status" : 415,
  "message" : "Content type 'application/x-www-form-urlencoded' not supported"
* STATE: PERFORM => DONE handle 0x600057830; line 1652 (connection #0)
* Curl_done
* Connection #0 to host api.everbridge.net left intact
}

回显 Mircea 建议的新脚本

$ ./Send_Not.sh
curl -vvv --include --header 'Accept:application/json' --header 'Authorization:Basic xxxxxxxxxxxxxxxxx' -X POST --data '{"sourceTemplateId":111111111111111}' --header Content-Type:application/json https://api.everbridge.net/rest/notifications/000000000000000

当我执行新脚本时回复

$ ./Send_Not.sh
Note: Unnecessary use of -X or --request, POST is already inferred.
* STATE: INIT => CONNECT handle 0x600057830; line 1108 (connection #-5000)
* Added connection 0. The cache now contains 1 members
*   Trying 54.193.84.167...
* STATE: CONNECT => WAITCONNECT handle 0x600057830; line 1161 (connection #0)
* Connected to api.everbridge.net (54.193.84.167) port 443 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x600057830; line 1260 (connection #0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* STATE: SENDPROTOCONNECT => PROTOCONNECT handle 0x600057830; line 1274 (connection #0)
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: C=US; ST=California; L=Glendale; O=Everbridge; OU=SaaS Operations; CN=*.everbridge.net
*  start date: Sep 18 00:00:00 2015 GMT
*  expire date: Sep 17 23:59:59 2018 GMT
*  subjectAltName: host "api.everbridge.net" matched cert's "*.everbridge.net"
*  issuer: C=US; O=GeoTrust Inc.; CN=GeoTrust SSL CA - G3
*  SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x600057830; line 1295 (connection #0)
> POST /rest/notifications/000000000000000 HTTP/1.1
> Host: api.everbridge.net
> User-Agent: curl/7.48.0
> Accept: */*
> 'Accept:application/json'
> 'Authorization:Basic xxxxxxxxxxxxxxxxx'
> Content-Type:application/json
> Content-Length: 39
>
* upload completely sent off: 39 out of 39 bytes
* STATE: DO => DO_DONE handle 0x600057830; line 1357 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x600057830; line 1484 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x600057830; line 1494 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
* Server nginx/1.8.0 is not blacklisted
< Server: nginx/1.8.0
Server: nginx/1.8.0
< Date: Wed, 18 May 2016 21:41:01 GMT
Date: Wed, 18 May 2016 21:41:01 GMT
< Content-Type: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Connection: keep-alive
Connection: keep-alive

<
{
  "status" : 400,
  "message" : "Error Unexpected character (''' (code 39)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')\n at [Source: org.apache.tools.ant.filters.StringInputStream@5d5906fc; line: 1, column: 2] parsing input:\n'{\"sourceTemplateId\":111111111111111}'"
* STATE: PERFORM => DONE handle 0x600057830; line 1652 (connection #0)
* Curl_done
* Connection #0 to host api.everbridge.net left intact
}

我也转义了Conten-Type的双引号,得到了原来的错误

#!/bin/bash
ajson="Accept:application/json"
credentials="Authorization:Basic xxxx_replace_xxxx"
data='{"sourceTemplateId":111111111111111}'
CT=\"Content-Type:application/json\"
url="https://api.everbridge.net/rest/notifications/000000000000000"

curl -vvv --include --header "$ajson" --header "$credentials" --data "$data" --header "$CT" "$url"

原来执行时出错

$ ./Send_Not.sh
Note: Unnecessary use of -X or --request, POST is already inferred.
* STATE: INIT => CONNECT handle 0x600057830; line 1108 (connection #-5000)
* Added connection 0. The cache now contains 1 members
*   Trying 54.193.84.167...
* STATE: CONNECT => WAITCONNECT handle 0x600057830; line 1161 (connection #0)
* Connected to api.everbridge.net (54.193.84.167) port 443 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x600057830; line 1260 (connection #0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* STATE: SENDPROTOCONNECT => PROTOCONNECT handle 0x600057830; line 1274 (connection #0)
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: C=US; ST=California; L=Glendale; O=Everbridge; OU=SaaS Operations; CN=*.everbridge.net
*  start date: Sep 18 00:00:00 2015 GMT
*  expire date: Sep 17 23:59:59 2018 GMT
*  subjectAltName: host "api.everbridge.net" matched cert's "*.everbridge.net"
*  issuer: C=US; O=GeoTrust Inc.; CN=GeoTrust SSL CA - G3
*  SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x600057830; line 1295 (connection #0)
> POST /rest/notifications/000000000000000 HTTP/1.1
> Host: api.everbridge.net
> User-Agent: curl/7.48.0
> Accept: */*
> 'Accept:application/json'
> 'Authorization:Basic xxxxxxxxxxxxxxxxxx'
> "Content-Type:application/json"
> Content-Length: 39
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 39 out of 39 bytes
* STATE: DO => DO_DONE handle 0x600057830; line 1357 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x600057830; line 1484 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x600057830; line 1494 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 415 Unsupported Media Type
HTTP/1.1 415 Unsupported Media Type
* Server nginx/1.8.0 is not blacklisted
< Server: nginx/1.8.0
Server: nginx/1.8.0
< Date: Wed, 18 May 2016 21:48:54 GMT
Date: Wed, 18 May 2016 21:48:54 GMT
< Content-Type: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Connection: keep-alive
Connection: keep-alive

<
{
  "status" : 415,
  "message" : "Content type 'application/x-www-form-urlencoded' not supported"
* STATE: PERFORM => DONE handle 0x600057830; line 1652 (connection #0)
* Curl_done
* Connection #0 to host api.everbridge.net left intact
}

正如评论中所述,这是一个关于你如何逃避事物的问题。
这是一种有效的脚本形式:

#!/bin/bash
ajson="Accept:application/json"
credentials="Authorization:Basic xxxx_replace_xxxx"
data='{"sourceTemplateId":111111111111111}'
CT="Content-Type:application/json"
url="https://api.everbridge.net/rest/notifications/000000000000000"

curl -vvv --include --header "$ajson" --header "$credentials" --data "$data" --header "$CT" "$url"