远程SSH执行Curl命令报错求助:连接拒绝及参数解析异常
我来帮你一步步排查这些SSH远程执行curl命令的问题,每个报错都对应着命令格式或转义的细节问题,咱们逐个拆解解决:
先逐个分析报错原因
1. 首次执行的「连接拒绝」错误
ssh root@x.x.x.x $(curl -H "Content-Type: application/json" -k -X POST -d '{"a":"value","ipAddress":"${variable}"}' https://localhost:9000/netconf/vm/maintenance/vm) % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (7) Failed connect to localhost:9000; Connection refused Last login: Fri Jun 1 09:38:01 2018 from 10.1.35.28
问题根源:你用了$(curl ...)的命令替换语法,这会让本地shell先执行curl命令,然后把curl的输出当作ssh要执行的远程命令。但本地机器并没有在9000端口运行对应服务,所以出现连接拒绝——而且这完全不符合你的需求,你要的是在远程机器上执行curl,不是本地执行后传结果。
2. 调整后的「主机解析错误+415媒体类型不支持」
# ssh root@x.x.x.x curl -H "Content-Type: application/json" -k -X POST -d '{"a":"value","ipAddress":"${variable}"}' https://localhost:9000/netconf/vm/maintenance/vm) % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (6) Could not resolve host: application; Unknown error 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (6) Could not resolve host: ipAddress; Unknown error {"timestamp":1527844486340,"status":415,"error":"Unsupported Media Type","exception":"org.springframework.web.HttpMediaTypeNotSupportedException","message":"100 291 0 251 100 40 2533 403 --:--:-- --:--:-- --:--:-- 2533aintenance/vm"}
问题根源:本地shell解析了你curl命令里的双引号,导致-H "Content-Type: application/json"被拆成了三个独立参数:-H、Content-Type:、application/json。curl误以为application是要访问的主机名,所以出现解析失败;同时因为没有正确设置Content-Type,服务器返回415错误。另外命令末尾多了一个右括号,也是语法问题。
3. 存入变量后的「400请求格式错误」
a='curl -H "Content-Type: application/json" -k -X POST -d '{"a":"value","ipAddress":"${variable}"}' https://localhost:9000/netconf/vm/maintenance/vm' # ssh root@x.x.x.x ${a} % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (6) Could not resolve host: ipAddress:10.1.35.38; Unknown error {"timestamp":1527847037512,"status":400,"error":"Bad Request","exception":"org.springframework.http.converter.HttpMessageNotReadableException","message":"Could not read document: Unrecognized token 'maintainanceMode': was expecting ('true', 'false' or 'null')\n at [Source: java.io.PushbackInputStream@339ead3; line: 1, column: 18]; nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'maintainanceMode': was expecting ('true', 'false' o100 633 0 593 100 40 5847 394 --:--:-- --:--:-- --:--:-- 584718]","path":"/netconf/vnfm/maintenance/vm"}
问题根源:定义变量a时用了单引号包裹,但里面的-d '{"a":"value"...}'又用了单引号,导致单引号嵌套失效——本地shell会把第一个单引号到第二个单引号之间的内容当作变量值,后面的{"a":"value"...}变成了额外的语法,最终传到远程的curl命令格式完全混乱,JSON被拆成多个参数,服务器无法解析。
针对性解决方案
根据${variable}是本地变量还是远程变量,分两种情况处理:
情况1:${variable}是远程机器的环境变量
用单引号把整个curl命令包裹,让本地shell不解析任何内容,完全传给远程执行:
ssh root@x.x.x.x 'curl -H "Content-Type: application/json" -k -X POST -d "{\"a\":\"value\",\"ipAddress\":\"${variable}\"}" https://localhost:9000/netconf/vm/maintenance/vm'
这里转义JSON里的双引号,是为了让远程shell解析${variable}时,保留JSON的结构。
情况2:${variable}是本地机器的环境变量
需要让本地先解析变量,再把完整命令传给远程,推荐用Here-doc避免多层转义,写法更清晰:
ssh root@x.x.x.x <<'EOF' curl -H "Content-Type: application/json" -k -X POST -d '{"a":"value","ipAddress":"'"${variable}"'"}' https://localhost:9000/netconf/vm/maintenance/vm EOF
<<'EOF'表示本地shell不解析Here-doc内的内容,除了'"${variable}"'这部分——它会把本地的${variable}值插入到远程的JSON字符串中,完美解决转义问题。
内容的提问来源于stack exchange,提问作者tgcloud

