Search code examples
bashmattermost

Escape whitespaces in a json defined in bash


I want to send a notification to our mattermost channel, if my build script fails:

test.sh

#!/bin/bash
set -eEx

projectName="$(grep '<name>' config.xml | sed "s@.*<name>\(.*\)</name>.*@\1@" | xargs)"
payload="payload={\"text\":\"${projectName}\"}\""

echo $payload

# notify mattermost channel "Jenkins Failures" in case this script fails
function notifyMattermostOnError() {
curl -i -X POST -d \
${payload} \
https://mattermost.company.com/hooks/<key>
}

notifyMattermostOnError

I'm extracting the the Project Name from a XML file, then putting it into the message. The extraction of the Project Name with grep/sed/xargs is working and is not my issue here.

projectName can be a string with whitespaces, f.ex. the value could be Company App. Running the When running the test.sh it will insert backticks:

mles:project mles$ ./test.sh 
++ grep '<name>' config.xml
++ sed 's@.*<name>\(.*\)</name>.*@\1@'
+ projectName='Company App'
+ payload='payload={"text":"Company App"}"'
+ echo 'payload={"text":"Company' 'App"}"'
payload={"text":"Company App"}"
+ notifyMattermostOnError
+ curl -i -X POST -d 'payload={"text":"Company' 'App"}"' https://mattermost.company.com/hooks/<key>
curl: (3) [globbing] unmatched close brace/bracket in column 8

The Problem is the payload json is being split into 'payload={"text":"Company' and 'App"}"'. How can I prevent this from happening? I'm already setting quotemarks around my strings.


Solution

  • At the very least, you need to quote the parameter expansion:

    curl -i -X POST -d "$payload" https://mattermost.company.com/hooks/<key>
    

    You should also use a tool that knows how to properly escape a string for use in JSON:

    payload="payload=$(jq -n --arg pn "$projectName" '{text :$pn}')"
    

    Finally, you should use a tool that knows XML to extract the project name, rather than hoping the XML is formatted in such a way that grep might work.

    projectName=$(xmlstarlet sel -t -v name config.xml)