amit singh
amit singh

Reputation: 209

escape " in bash inside json

This might easy thing that i am missing, but i have a script for single host now i want create same script for all host.

Below is the code i am using

    {while read -r host
do

ho=$host
an=some_alert_$host
tick="// Host of the machine\nvar host = '"$ho"'\n\n// durations\nvar period = 7m\n\nvar every = 6m\n\n// alerts\nvar warn = 75\n\nvar crit = 85\n\n// database\nvar database = 'xxx'\n\n// measurement from where data is coming\nvar measurement = 'disk'\n\n// RP from where data is coming\nvar RP = 'autogen'\n\n// which influx cluster to use\nvar clus = 'xxx'\n\nvar alertName = '"$an"'\n\nvar triggerType = 'threshold'\n\nbatch\n    |query('''SELECT last(\"used_percent\") as \"value\" FROM \"''' + string(database) + '''\".\"''' + string(RP) + '''\".\"''' + string(measurement) + '''\" where host = \"''' + string(host) + '''\" ''')\n        .cluster(clus)\n        .period(period)\n        .every(every)\n        .groupBy(*)\n        .align()\n    |alert()\n        .warn(lambda: \"value\" \u003e warn)\n        .crit(lambda: \"value\" \u003e crit)\n        .stateChangesOnly()\n        .message(' {{ index .Tags \"path\" }} used {{ index .Fields \"value\" | printf \"%0.2f\" }}% disk space on {{ .Time.Local.Format \"2006.01.02 - 15:04:05\" }} in {{ index .Tags \"host\" }} ')\n        .details('''\n\n \u003cpre\u003e\n ------------------------------------------------------------------\n CLIENT NAME      : xxx\n ENVIRONMENT      : Prod\n DEVICE TYPE      : {{ index .Tags \"os\" }}\n APPLICATION NAME : {{ index .Tags \"app_stack\" }}\n HOST NAME        : {{ index .Tags \"host\" }}\n IP ADDRESS       : {{ index .Tags \"ip\" }}\n DATE             : {{ .Time.Local.Format \"2006.01.02 - 15:04:05\" }}\n ITEM NAME        : {{ index .Tags \"path\" }} Disk Utilization (%)\n VALUE            : {{ index .Fields \"value\" | printf \"%0.2f\" }} %\n SEVERITY         : {{.Level}}\n ------------------------------------------------------------------\n \u003c/pre\u003e\n\t\n''')\n        .log('/tmp/chronograf/$an.log')\n        .levelTag('level')\n        .idTag('id')\n        .messageField('message')\n        .email()\n        .to('xxx')\n    |influxDBOut()\n        .database('chronograf')\n        .retentionPolicy(RP)\n        .measurement('alerts')\n        .tag('alertName', alertName)\n" 


echo "{
  \"id\": "some_alert_$host",
  \"type\": \"batch\",
  \"dbrps\": [
    {
      \"db\": \"kenan\",
      \"rp\": \"autogen\",
      \"name\": \"kenan.autogen\"
    }
  ],
  \"tickscript\": "$tick"
}"

done < host}

In here tick variable is the first script, but when i call the tick variable in json it removes the \ in front of ".

Upvotes: 0

Views: 144

Answers (1)

chepner
chepner

Reputation: 531798

Don't try to apply JSON encoding manually, especially in conjunction with interpolation. Use jq to generate your JSON; it will encode everything as necessary, letting you define tick as an ordinary string.

while read -r host
do

  ho=$host
  an=some_alert_$host

# Generate the script as you normally would, not as a JSON string
  tick="// Host of the machine
var host = '$ho'
// durations
var period = 7m

var every = 6m

// alerts
var warn = 7

var crit = 85

//etc. " 


  jq -n --arg an "$an" --arg tick "$tick" \
    '{id: $an, type: "batch", dbrps: [{db: "kenan", rp: "autogen", name: "kenan.autogen"}], tickscript: $tick}'


done < host

You may also want to sanitize the value of ho before defining tick, to ensure the result really is a valid script.

Upvotes: 3

Related Questions