在远程服务器上运行命令以构造JSON字符串

时间:2018-10-29 21:55:48

标签: json bash ssh quotes

我需要获取删除服务器的本地时间和主机名。

以下命令在本地服务器上正确执行。

echo "{\"hostname\":\"`hostname`\" , \"date\":\"`date '+%Y-%m-%d %H:%M:%S'`\"}"

并正确返回以下输出:

{"hostname":"server1" , "date":"2018-10-29 17:43:51"}

但是当我在远程服务器上执行相同的命令时,它将失败:

var1=`ssh server2 " echo "{\"hostname\":\"`hostname`\" , \"date\":\"`date '+%Y-%m-%d %H:%M:%S'`\"}" "`
  

bash:“:找不到命令

     

bash:+%Y-%m-%d%H:%M:%S:找不到命令

`ssh server2 " echo "{\"hostname\":\"`hostname`\" , \"date\":\"`date '+%Y-%m-%d %H:%M:%S'`\"}" "`
  

bash:“:找不到命令

     

bash:“}:找不到命令

     

bash:{hostname:hostnamedate:命令未找到

3 个答案:

答案 0 :(得分:1)

尝试:

var1=$(ssh server2 " echo "{\"hostname\":\"\$\(hostname\)\" , \"date\":\"\$\(date '+%Y-%m-%d %H:%M:%S'\)\"}" ")

基本上,您不能嵌套''反引号,因此必须使用$()并且要转义要远程执行的命令(主机名和日期)。

答案 1 :(得分:1)

使用bash -s和带引号的heredoc可以完全按原样运行您的代码,而无需进行任何更改:

ssh server2 bash -s <<'EOF'
echo "{\"hostname\":\"`hostname`\" , \"date\":\"`date '+%Y-%m-%d %H:%M:%S'`\"}"
EOF

也就是说,通常,使用字符串连接生成JSON是个坏主意(如果您的命令返回意外的输出,则可能导致输出实际上不是有效的JSON)。考虑当内容通过SSH传递时用换行符分隔内容,然后使用jq这样的语法感知工具在本地生成JSON:

IFS=$'\n' read -r -d '' hostname date < <(
  ssh server2 'hostname && date +"%Y-%m-%d %H:%M:%S" && printf "\0"'
)
jq --arg hostname "$hostname" --arg date "$date" \
  '{ "hostname": $hostname, "date": $date }'

答案 2 :(得分:1)

Charles'答案最适合JSON。如果您没有ring,可以这样做:

jq