0

I am using this bash script to post a new message to my rocket.chat instance.

#!/usr/bin/env bash
function usage {
    programName=$0
    echo "description: use this program to post messages to Rocket.chat channel"
    echo "usage: $programName [-b \"message body\"] [-u \"rocket.chat url\"]"
    echo "      -b    The message body"
    echo "      -u    The rocket.chat hook url to post to"
    exit 1
}
while getopts ":b:u:h" opt; do
  case ${opt} in
    u) rocketUrl="$OPTARG"
    ;;
    b) msgBody="$OPTARG"
    ;;
    h) usage
    ;;
    \?) echo "Invalid option -$OPTARG" >&2
    ;;
  esac
done
if [[ ! "${rocketUrl}" || ! "${msgBody}" ]]; then
    echo "all arguments are required"
    usage
fi
read -d '' payLoad << EOF
{"text": "${msgBody}"}
EOF
echo $payLoad
statusCode=$(curl \
        --write-out %{http_code} \
        --silent \
        --output /dev/null \
        -X POST \
        -H 'Content-type: application/json' \
        --data "${payLoad}" ${rocketUrl})
echo ${statusCode}

Everthings works fine, so i can send a new message like this

./postToRocket.sh -b "Hello from here" -u $RocketURL

But when i try to add a message with multiple lines like this

./postToRocket.sh -b "Hello from here\nThis is a new line" -u $RocketURL

it doesn't work. I get the following output:

{"text": "Hello from heren New Line"}
200

So what do i need to change, to use break line with these bash script. Any ideas?

Cyrus
  • 84,225
  • 14
  • 89
  • 153
Niklas
  • 1,638
  • 4
  • 19
  • 48
  • Does this answer your question? [How to send line break with curl?](https://stackoverflow.com/questions/3872427/how-to-send-line-break-with-curl); review the various answers for a few ideas on how to submit a line break to `curl` – markp-fuso Oct 23 '20 at 18:28
  • Part of the problem is that `read` mangles backslashes when you don't use it with `-r`; the _larger_ problem is that even if you didn't have backslashes mangled, your result still wouldn't be legal JSON, so the remote server couldn't be expected to accept it. JSON documents need to have `\n` sequences, not newlines. – Charles Duffy Oct 23 '20 at 18:42

2 Answers2

2

First, the thing making the backslash in your \n disappear was the lack of the -r argument to read. Making it read -r -d '' payLoad will fix that. However, that's not a good solution: It requires your callers to pass strings already escaped for inclusion in JSON, instead of letting them pass any/every possible string.


To make valid JSON with an arbitrary string -- including one that can contain newline literals, quotes, backslashes, or other content that has to be escaped -- use jq:

payLoad=$(jq -n --arg msgBody "$msgBody" '{"text": $msgBody}')

...and then, after doing that, amend your calling convention:

./postToRocket.sh -b $'Hello from here\nThis is a new line' -u "$RocketURL"
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
0

I believe this has already been answered in SO here

Should work by adding the $ sign and using single quotes:

./postToRocket.sh -b $'Hello from here\nThis is a new line' -u $RocketURL
Marc
  • 2,183
  • 2
  • 11
  • 16