67

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

101

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.

5
  • 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
  • 1
    I'm always surprised every time I am reminded that bash just concatenates strings without any operator.
    – scubbo
    Oct 12, 2022 at 1:17
6

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"'.}'
2

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, 2022 at 7:49

You must log in to answer this question.

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