61

Trying to get Transmission to notify when download complete.

This works:

curl -u <my-api-token>: \
  -X POST https://api.pushbullet.com/v2/pushes \
  --header 'Content-Type: application/json' \
  --data-binary '{"type": "note", "title": "$TR_TORRENT_NAME", \
  "body": "$TR_TORRENT_NAME completed."}'

... except it pushes $TR_TORRENT_NAME and not the actual contents of that variable.

Do I need to escape some quote or something?

1
  • save 10 seconds and just use single quote again in variable ' "$TR_TORRENT_NAME completed" '
    – Adiii
    Dec 14, 2020 at 4:34

3 Answers 3

95

Inside single-quotes, the shell expands nothing. Place them inside double-quotes instead:

curl -u <my-api-token>: \
  -X POST https://api.pushbullet.com/v2/pushes \
  --header 'Content-Type: application/json' \
  --data-binary '{"type": "note", "title": "'"$TR_TORRENT_NAME"'", \
  "body": "'"$TR_TORRENT_NAME completed"'."}'

Let's examine how this works by looking at:

$ TR_TORRENT_NAME=MyTorrent
$ echo '{"type": "note", "title": "'"$TR_TORRENT_NAME"'", "body": "'"$TR_TORRENT_NAME completed"'."}'
{"type": "note", "title": "MyTorrent", "body": "MyTorrent completed."}

When the shell variable appears, it is always inside double-quotes. Consequently, it is properly expanded.

Quoting like this is a bit subtle. We have single-quoted strings that contain double-quotes as characters and are next to double-quoted strings. To understand this better, let's take this fragment as a an example:

 "'"$TR_TORRENT_NAME"'"

Taking each character in turn:

  1. " is a literal double-quote character that is inside of a single-quoted string. (For brevity, the beginning of this string is not shown in this fragment.)

  2. ' closes a single-quoted string.

  3. " opens a double-quoted string.

  4. $TR_TORRENT_NAME is a shell variable that is expanded inside double-quotes.

  5. " closes the double-quoted string.

  6. ' opens a new single-quoted string.

  7. " places a double-quote character inside the single-quoted string.

4
  • Do you need steps 3 and 5? Jan 18, 2018 at 11:39
  • @davidfrancis If one omits steps 3 and 5, then step 4 is subject to word splitting and pathname expansion and either one could cause all manor of trouble. Unless one explicitly wants word splitting and pathname expansion, a shell variable should always be inside double-quotes.
    – John1024
    Jan 18, 2018 at 20:49
  • Thanks for that, can you give a quick example please? It worked in my own example, which is why I asked, but there were no spaces or anything else complex in there Jan 19, 2018 at 9:10
  • @davidfrancis Try TR_TORRENT_NAME="A * B" and see what happens.
    – John1024
    Jan 20, 2018 at 8:17
4

To include an environment variable in a bash line curl without quotes around the variable content, this worked for me:

--header 'PRIVATE-TOKEN: '"$PRIVATE_TOKEN"''

Or using the scenario that was first described without quotes around the body field:

curl -u <my-api-token>: \
  -X POST https://api.pushbullet.com/v2/pushes \
  --header 'Content-Type: application/json' \
  --data-binary '{"type": "note", "title": "'"$TR_TORRENT_NAME"'", \
  "body": '"$TR_TORRENT_NAME completed"'.}'
0

Put quotes at the end and double quotes around the environment variable is the easiest way:

  1. Initialize and export the variable-

     export TR_TORRENT_NAME="foo"
    
  2. Import the variable-

     echo  "{"type": "note", "title": ""$TR_TORRENT_NAME"", "body": ""$TR_TORRENT_NAME"" "completed."}"
    
  3. The response would look like-

     {type: note, title: foo, body: foo completed.}
    
1
  • 1
    The output is not a valid json. See John1024's answer above
    – ozma
    May 4 at 7:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.