-2

Here is my simple script

#!/bin/sh
thefile=/home/ark/arkserver/ShooterGame/Saved/SaveIsland/1288804998.arktribe

while inotifywait "${thefile}" ; do
    a=\"`strings ${thefile} | tail -n 5 | head -n 1 | sed 's/<[^>]*>//g'`\"
echo $a

curl -H "Content-Type: application/json" -X POST -d '{\"username\": \"Island\", \"content\": $a}' https://discordapp.com/api/webhooks/5738674701/OjRQiAWHq5mX0Tn2MfBlF-mI41TWrVYVAbOfXpeZWqo8

done

Here is the output

Setting up watches.
Watches established.
/home/ark/arkserver/ShooterGame/Saved/SaveIsland/1288804998.arktribe ATTRIB
"Day 600, 21:31:17: Phorce1 demolished a 'Campfire'!"
{"code": 50006, "message": "Cannot send an empty message"}Setting up watches.
Watches established.

I cannot figure out how to get the curl command properly quoted with the variable inserted in the middle. This is what the command should look like. This works when typed out on the command line

curl -H "Content-Type: application/json" -X POST -d '{"username": "test", "content": "Day 600, 14:51:00: Phorce1 demolished a 'Campfire'!"}' https://discordapp.com/api/webhooks/594723628738674701/OjRQn2MfBlF-FJVl1cWwMlD6UQf0c

I have tried many different forms of quoting. The fact that it echos $a as properly quoted but still breaks something in the command that uses it confuses me.

(Yes, I mangled my webhook address)

This question was marked as a duplicate to another question, but the answers to that question were to simply escape the quotes. The "nested quotes" nature of the curl command line in my script causes those answers to fail. I tried many forms of escaping the quotes before posting my own question. Using escaped quotes as mentioned in the answer on the other question I could get a simple "echo" of the variable inside quotes with no problem but inserting that "inside the quotes that were inside other quotes that were inside another set of quotes" in the curl command line would fail.

1
  • @rush Please note the answer I selected here is quite different from the replies to that question. I tried escaping the quotes around the variable but the "many nested quotes" nature of he curl command line cause that to fail. So, no, this is not a duplicate of that question.
    – Phorce1
    Commented Jul 2, 2019 at 0:13

2 Answers 2

4

Single quotes prevent variable expansion.

I would do this:

url=https://discordapp.com/api/webhooks/5738674701/OjRQiAWHq5mX0Tn2MfBlF-mI41TWrVYVAbOfXpeZWqo8
while inotifywait "$thefile" ; do
    a=$(strings "$thefile" | tail -n 5 | head -n 1 | sed 's/<[^>]*>//g')
    echo "$a"
    payload=$(printf '{"username": "Island", "content": "%s"}' "$a")
    curl -H "Content-Type: application/json" -X POST -d "$payload" "$url" 
done

You don't need to escape double quotes inside of single quotes. In fact, if you do, the escape will be preserved as a literal character.

Always quote your variables, unless you know exactly what might happen if you don't.

(This is a matter of personal style) You don't need to brace a variable inside of quotes, unless you need to disambiguate the variable name from surrounding text:

echo "$aVariable"
echo "${aVariable}_abc"
1
  • Thank you. I write little scripts so seldom I had to go look up a refresher on printf to figure out what the %s was doing. I was also looking at other similar questions that suggested creating a function for the curl command but this, fixing my quoting using variables, feels more right to me.
    – Phorce1
    Commented Jul 1, 2019 at 16:45
0

To create a JSON document containing user-provided data, and correctly encode it etc., use something like jq:

payload=$( jq --arg content "$data" -n '{"username": "Island", "content": $content}' )

This would create a small JSON document in $payload that contains the value of $data in in the value field of the content key. The value will be properly quoted (things like double quotes and non-ASCII characters will be handled correctly).

For example, if $data is, literally

"hello
world"

(including quotes and newline), the command above would create the following JSON document and assign it to tho payload variable:

{
  "username": "Island",
  "content": "\"hello\nworld\""
}

To delete useless whitespace in the generated document, use jq with its -c option.

The full script would look like

#!/bin/sh

url='https://discordapp.com/api/webhooks/5738674701/OjRQiAWHq5mX0Tn2MfBlF-mI41TWrVYVAbOfXpeZWqo8'
file='/home/ark/arkserver/ShooterGame/Saved/SaveIsland/1288804998.arktribe'

while inotifywait "$file" ; do
    data=$( strings "$file" | tail -n 5 | head -n 1 | sed 's/<[^>]*>//g' )
    payload=$( jq --arg content "$data" -n '{"username": "Island", "content": $content}' )

    curl -H "Content-Type: application/json" \
         -X POST \
         -d "$payload" \
         "$url"
done

The only quoting you need to worry about is of the shell variables, which should be double quoted as usual. There is no need to try to insert literal quotes into the data read from your pipeline.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .