1

I have a shell program which write multiline output to a variable called "$text" which outputs as below on terminal.

echo "$text"

==============================================
Oracle Host: xxxxxxxxx
==============================================
orcl:
Database UP -- OK
Listener UP -- OK
Database Read&Write Mode -- OK
Instance Status -- OK
Instance Login Allowed -- OK
---------------------------------------------
orcltest:
Database UP -- OK
Listener UP -- OK
Database Read&Write Mode -- OK
Instance Status -- OK
Instance Login Allowed -- OK
---------------------------------------------

Now to trying to post this as above output in slack channel, so trying to read the lines from above variable with code below:

while IFS= read -r line; do
#printf '%s\n' "$line"
text="$text$line\n"
done <<< "$text"
escapedText=$(echo $text | sed 's/"/\\"/g; s/'\''/\\'\''/g' )
json="{\"channel\": \"#$channel\", \"text\": \"$escapedText\"}"
curl -X POST --data-urlencode "payload=$json" https://hooks.slack.com/services/xxxxx/xxxx/xxxxx"

its showing error like:

missing_text_or_fallback_or_attachments

but in above code I guess while loop is not working properly...is that correct way of reading multi line variable and pass on to payload in curl statement

Erik Kalkoken
  • 30,467
  • 8
  • 79
  • 114
asp
  • 777
  • 3
  • 14
  • 33
  • First find out more details where something is going wrong. I think the error shown comes from `curl`, add `echo "payload=${json}" before calling curl. After this the question can be reduced to `why is the json like .. ` or `why does curl give error on the next payload`. – Walter A Nov 18 '18 at 11:49
  • thanks for clarification.. i just echoed `payload={"channel": "#are_you_listening", "text": "============================================== Oracle Host: xxxxxxx ============================================== orcl: Database UP -- OK Listener UP -- OK Database Read&Write Mode -- OK Instance Status -- OK Instance Login Allowed -- OK --------------------------------------------- orcltest: Database UP -- OK Listener UP -- OK Database Read&Write Mode -- OK Instance Status -- OK Instance Login Allowed -- OK --------------------------------------------- \n"}`. It says invalid payload – asp Nov 18 '18 at 12:45
  • Your `escapedText=$(echo $text | sed 's/"/\\"/g; s/'\''/\\'\''/g' )` is missing double quotes around `$text`. Your example text is without quotes, maybe first try without escaping the text. – Walter A Nov 18 '18 at 23:05
  • What are you trying with the while loop? Try `escapedText="${text}" without the loop. – Walter A Nov 18 '18 at 23:07
  • Actually i am using while loop for reading line by line from variable and print it to slack. any way let me try escapedText="${text}" without the loop – asp Nov 19 '18 at 01:43
  • Wow Wow, finally worked by mentioning escapedText="${text}" without the loop. Thanks a ton. Since in a different method i was reading file content line by line by loop for escaped text, I thought I should the same for multiline content in variable too.. Not really sure why such difference in reading multiline from a file vs multiline read in variable though ? – asp Nov 19 '18 at 02:07

3 Answers3

1

The escapedText=$(echo $text | sed 's/"/\\"/g; s/'\''/\\'\''/g' ) can cause problems. The $text should be quoted when you do not want the shell to interpret the data (eat spaces and newlines, get confused by special characters).

The loop reading from the var is not needed and might give problems when the last character in the var is not a \n. The read command only reads "complete lines", anything after the last \n is ignored.
This problem is also possible when reading from a file. Most times when a file has been created (using vi or echo "Something" > file) the file will be created with a closing \n. The loop, filling a var $text with the contents of $text is not needed.

Walter A
  • 19,067
  • 2
  • 23
  • 43
0

I think you are not using the correct format and syntax for your POST to webhook.

The correct format is raw POST with a JSON body like so:

POST https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
Content-type: application/json
{
    "text": "Hello, world."
}

But you have a weird payload parameter in your curl. Also you need to set JSON as content type.

Assuming your JSON syntax is correct, this should work:

curl https://hooks.slack.com/services/xxx -X POST -H "Content-type: application/json" --data '$json'
Erik Kalkoken
  • 30,467
  • 8
  • 79
  • 114
  • Thanks for reply. the above format also not working... actually I tried different method writing that terminal output to txt file and using below code to read line by line `while IFS= read -r line; do #printf '%s\n' "$line"text="$text$line\n" done < /home/oracle/abc.log'` and same old curl statement working fine..But what i am trying to do is not use writing a file and then read it from it, instead i want to assign that multiline output to a variable and read variable with similar fashion with below code `while IFS= read -r line; do text="$text$line\n" done <<< $text` which not working – asp Nov 18 '18 at 17:23
  • looking at your json above it looks like your quotation marks are not escaped. you can fix that by going from double to single quotation marks in the curl `--data` parameter. i update my example – Erik Kalkoken Nov 18 '18 at 18:27
0

Thanks to @Walter A @Erik Kalkoken for your time and help

Ultimately what worked is as per Walter A, I just replaced

escapedText=$(echo $text | sed 's/"/\"/g' | sed "s/'/\'/g" )

with

escapedText="${text}"

and removed below section together looping through text

while IFS= read -r line; do
#printf '%s\n' "$line"
text="$text$line\n"
done <<< "$text"
asp
  • 777
  • 3
  • 14
  • 33