【问题标题】:How to pass a variable in a JSON string in bash script如何在 bash 脚本中传递 JSON 字符串中的变量
【发布时间】:2021-06-29 15:38:48
【问题描述】:

我有以下脚本,同时从主机获取一些命令输出并将其保存到文件 /tmp/${stcl}_aggr.txt 中,进一步将该文件放置到变量 body=$(cat /tmp/${stcl}_aggr.txt) 中

虽然将此变量 body 调用到 Jason 数组中作为 "description": "$body" 它的值没有得到扩展并导致错误为 KeyError: 'result',并且像 incident_number、curloutput 这样的变量也不起作用,而如果我删除 body 为 "description": 然后脚本将运行,但我需要上传 "description": 值。

#!/bin/bash
#
DATE=$(date +"%m_%d_%Y_%H_%M")
mailto="udc@example.com"
cwd="/myenv/filer-mgt/bin"
output="/my_env/filer-mgt/rpt/$DATE"
clusters="udcl301 "

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:$PATH
incident=$1
sysid=UNKNOWN

checkvaultenv=`echo $vaultenv | tr '[:upper:]' '[:lower:]'`
if [[  "$checkvaultenv" == "" ]]
then
  vaultenv=prod
else
  if [[  "$checkvaultenv" != "dev" &&  "$checkvaultenv" != "test" && "$checkvaultenv" != "acc" && "$checkvaultenv" != "prod" ]]
  then
    echo unknown vault environment specified: $vaultenv
    exit 1
  fi
fi
vaultenvlc=`echo $vaultenv | tr '[:upper:]' '[:lower:]'`
vaultenvuc=`echo $vaultenv | tr '[:lower:]' '[:upper:]'`


SNOW_USERNAME=`export EDITOR=cat ; ansible-vault edit --vault-password-file=~/.ssh/vpf.iss.${vaultenvlc} ~/iss/vaults/vault-${vaultenvuc}.yml | grep vault_servicenow_username | grep -v -E  "^\s*#" | awk '{print $2}' FS=\"`
SNOW_PASSWORD=`export EDITOR=cat ; ansible-vault edit --vault-password-file=~/.ssh/vpf.iss.${vaultenvlc} ~/iss/vaults/vault-${vaultenvuc}.yml | grep vault_servicenow_password | grep -v -E  "^\s*#" | awk '{print $2}' FS=\"`

case $vaultenvlc in
  ram)
    SNOW_INSTANCE=udc2dev.service-now.com
    ;;
  iqa)
    SNOW_INSTANCE=udc2dev.service-now.com
    ;;
  dev)
    SNOW_INSTANCE=udc2dev.service-now.com
    ;;
  test)
    SNOW_INSTANCE=udc2trn.service-now.com
    ;;
  acc)
    SNOW_INSTANCE=udc2qa.service-now.com
    ;;
  *)
    SNOW_INSTANCE=udc2.service-now.com
    ;;
esac

SNOW_AUTH=`echo -n $SNOW_USERNAME:$SNOW_PASSWORD`

create_incident()
{
  url="https://${SNOW_INSTANCE}/api/now/table/incident"
  curloutput=`curl -sslv1 -u $SNOW_AUTH -X POST -s -H "Accept:application/json" -H "Content-Type:application/json" $url -d "$variables" 2>/dev/null`
  RETURNCODE=$?
  if [ "$RETURNCODE" == "0" ]
  then
    incident_number=`echo $curloutput |  python -c $'import sys, json\nprint json.load(sys.stdin)["result"]["number"]'`
    sysid=`echo $curloutput |  python -c $'import sys, json\nprint json.load(sys.stdin)["result"]["sys_id"]'`
    echo "OK: created incident $incident_number with sysid $sysid"
  else
    echo "ERROR creating incident:"
    echo "======================================="
    echo $curloutput
    echo "======================================="
  fi
}

#create_incident
for udcl in `echo $clusters`
do
  ssh $udcl aggr show -root false | grep -i "9[2-9]%\|100%" >  /tmp/${udcl}_aggr.txt
  snshort_description="aggr utilization above limit"
  sncmdb_ci=$udcl
  body="`cat /tmp/${udcl}_aggr.txt`"

read -r -d '' variables <<- EOM
{
  "short_description": "$snshort_description",
  "assignment_group":  "RD-DI-Infra-Storage",
  "contact_type":      "interface",
  "state":             "New",
  "urgency":           "3 - Low",
  "impact":            "3 - Low",
  "cmdb_ci":           "$sncmdb_ci",
  "u_sec_env":         "Normal Secure",
  "description":       "$body"
}
EOM

echo $variables

  create_incident


ssh $udcl "ro 0;vol show -state offline -fields aggregate"|grep stv > /tmp/${udcl}_validate_offline_volume.txt
done

错误:

我在运行上面的时候看到下面的错误..

[root@inv0104 tmp]# ./K_storage_healt_check.sh
{ "short_description": "aggr utilization above limit", "assignment_group": "RD-DI-Infra-Storage", "contact_type": "interface", "state": "New", "urgency": "3 - Low""' }mpact": "3 - Low", "cmdb_ci": "udcl301", "u_sec_env": "Normal Secure", "description": '"udc3019_ssd02 93.89TB 6.10TB 93% online 391 udc3019 raid_dp,
Traceback (most recent call last):
  File "<string>", line 2, in <module>
KeyError: 'result'
Traceback (most recent call last):
  File "<string>", line 2, in <module>
KeyError: 'result'

在调试模式下运行时,我看到更多错误,例如..

+ curloutput='{"error":{"detail":"Cannot decode: java.io.StringReader@6b4762","message":"Exception while reading request"},"status":"failure"}'
+ RETURNCODE=0
+ '[' 0 == 0 ']'
++ echo '{"error":{"detail":"Cannot' decode: 'java.io.StringReader@6b4762","message":"Exception' while reading 'request"},"status":"failure"}'
++ python -c 'import sys, json
print json.load(sys.stdin)["result"]["number"]'
Traceback (most recent call last):
  File "<string>", line 2, in <module>
KeyError: 'result'
+ incident_number=
++ echo '{"error":{"detail":"Cannot' decode: 'java.io.StringReader@6b4762","message":"Exception' while reading 'request"},"status":"failure"}'
++ python -c 'import sys, json
print json.load(sys.stdin)["result"]["sys_id"]'
Traceback (most recent call last):
  File "<string>", line 2, in <module>
KeyError: 'result'
+ sysid=
+ echo 'OK: created incident  with sysid '
OK: created incident  with sysid

看起来像 json 或 python 的问题,我无法到达这里。

有问题的部分:

 ssh $udcl aggr show -root false | grep -i "9[2-9]%\|100%" >  /tmp/${udcl}_aggr.txt
  body="`cat /tmp/${udcl}_aggr.txt`"

read -r -d '' variables <<- EOM
{
  "description":       "$body"
}
EOM

如果我删除$body,那么整个脚本将运行得很好,因此它的全部内容都是关于变量$body,它没有得到解释。

【问题讨论】:

  • 您能否将您的代码 sn-p 缩减为产生问题的最小样本?
  • 为什么不用python替换那个bash脚本呢?我看到你已经在某些地方使用了 python。 Bash 对一些简单的任务很有帮助,但当复杂性增加时,它可能不是正确的工具。
  • @HernánAlarcón,我不擅长python,可能稍后会考虑。
  • @MrR,我已经编辑了代码并保留了错误的一小部分。
  • @Kulfi 你能添加这个ssh $udcl aggr show -root false | grep -i "9[2-9]%\|100%" 的输出吗?

标签: python json bash


【解决方案1】:

我可以复制类似于我的实验室,所以,根据我的理解,下面应该适合你。

ssh $udcl aggr show -root false | grep -i "9[2-9]%\|100%"  | sed 's/\(.*\)\r/"\1"/g' >  /tmp/${udcl}_aggr.txt

说明:

您的输入文件在行尾有回车符,因此要删除相同的内容,我们可以在“grep”之后使用上面的 sed,然后您不需要将 body 变量双引号作为数据行内变量已被引用,并且 json 喜欢这样。

【讨论】:

  • 谢谢卡恩库马尔?,它就像一个魅力!
  • 或者可以尝试| tr -d '\r'而不是thru sed。
猜你喜欢
  • 2018-11-28
  • 2018-12-07
  • 1970-01-01
  • 1970-01-01
  • 2015-09-04
  • 2015-12-18
  • 2016-01-19
  • 2020-05-24
  • 1970-01-01
相关资源
最近更新 更多