2

I need to execute a curl command like this:

#!/bin/bash

shopid=9932781
itemid=231873991
curl -sSb /tmp/cookies 'https://website.com' -H 'cookie: csrftoken=mytoken' -H 'x-csrftoken: mytoken' -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary' -H 'referer: https://website.com' \
  --data-binary $'------WebKitFormBoundary\r\nContent-Disposition: form-data; name="shopid"\r\n\r\n${shopid}\r\n------WebKitFormBoundary\r\nContent-Disposition: form-data; name="itemid"\r\n\r\n${itemid}\r\n------WebKitFormBoundary\r\nContent-Disposition: form-data; name="quantity"\r\n\r\n1\r\n------WebKitFormBoundary\r\nContent-Disposition: form-data; name="donot_add_quantity"\r\n\r\nfalse\r\n------WebKitFormBoundary\r\nContent-Disposition: form-data; name="update_checkout_only"\r\n\r\nfalse\r\n------WebKitFormBoundary\r\nContent-Disposition: form-data; name="source"\r\n\r\n\r\n------WebKitFormBoundary\r\nContent-Disposition: form-data; name="checkout"\r\n\r\ntrue\r\n------WebKitFormBoundary--\r\n'

The $'' quotes are necessary or else (ie. in the double-quoted case) \r\n won't work -- but with this form, $shopid and $item aren't replaced with their values.

How can I get both behaviors?

codeforester
  • 39,467
  • 16
  • 112
  • 140
Joe
  • 791
  • 1
  • 9
  • 24
  • 1
    Take a look at: [Difference between single and double quotes in Bash](https://stackoverflow.com/questions/6697753/difference-between-single-and-double-quotes-in-bash) – codeforester Mar 21 '18 at 21:42

3 Answers3

3

You need to make that code maintainable

binary_data=$( cat <<END_DATA | sed 's/$/\r/'
------WebKitFormBoundary
Content-Disposition: form-data; name="shopid"

${shopid}
------WebKitFormBoundary
Content-Disposition: form-data; name="itemid"

${itemid}
------WebKitFormBoundary
Content-Disposition: form-data; name="quantity"

1
------WebKitFormBoundary
Content-Disposition: form-data; name="donot_add_quantity"

false
------WebKitFormBoundary
Content-Disposition: form-data; name="update_checkout_only"

false
------WebKitFormBoundary
Content-Disposition: form-data; name="source"


------WebKitFormBoundary
Content-Disposition: form-data; name="checkout"

true
------WebKitFormBoundary--
END_DATA
)

curl_opts=( 
    -sSb /tmp/cookies 
    -H 'cookie: csrftoken=mytoken' 
    -H 'x-csrftoken: mytoken' 
    -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary' 
    -H 'referer: https://website.com' 
    --data-binary "$binary_data"
)

curl "${curl_opts[@]}" 'https://website.com' 
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
1

The variables are not expanded in 'single quotes'.

It's important to learn how quoting works :

"Double quote" every literal that contains spaces/metacharacters and every expansion: "$var", "$(command "$var")", "${array[@]}", "a & b". Use 'single quotes' for code or literal $'s: 'Costs $5 US', ssh host 'echo "$HOSTNAME"'. See http://mywiki.wooledge.org/Quotes
http://mywiki.wooledge.org/Arguments
http://wiki.bash-hackers.org/syntax/words


So, try this :

data="------WebKitFormBoundary
Content-Disposition: form-data; name='shopid'

${shopid}
------WebKitFormBoundary
Content-Disposition: form-data; name='itemid'

${itemid}
------WebKitFormBoundary
Content-Disposition: form-data; name='quantity'

1
------WebKitFormBoundary
Content-Disposition: form-data; name='donot_add_quantity'

false
------WebKitFormBoundary
Content-Disposition: form-data; name='update_checkout_only'

false
------WebKitFormBoundary
Content-Disposition: form-data; name='source'


------WebKitFormBoundary
Content-Disposition: form-data; name='checkout'

true
------WebKitFormBoundary--"

data="$(sed 's/$/\r/' <<< "$data")"

curl -sSb /tmp/cookies \
    -H 'cookie: csrftoken=mytoken' \
    -H 'x-csrftoken: mytoken' \
    -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary' \
    -H 'referer: https://website.com' \
    --data-binary "$data" \
    'https://website.com' 
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
  • I just need to know how to make that curl command work, I know single quotes won't return variables but simply replacing single quotes with double quotes on that curl command won't solve the problem. – Joe Mar 21 '18 at 21:43
  • Because using double quotes also doesn't solve the problem – Joe Mar 21 '18 at 21:46
  • Thanks but I would put the post data in a variable just to make the curl command a bit shorter. – Joe Mar 21 '18 at 21:59
  • Take attention of the quoting way in the data to prevent conflict or the need to backslash/protect double quotes – Gilles Quénot Mar 21 '18 at 22:07
  • I just tried your solution but it didn't work, it looks like you have to use sed just like the answer of glenn jackman above – Joe Mar 21 '18 at 22:09
  • In `sed 's/$/\r/'` may I know where you get the dollar sign from ? are you replacing the dollar signs from `${shopid}` and `${itemid}` ? and why are there three `<<<` I often only see 2 ? – Joe Mar 22 '18 at 14:15
  • The $ is an _anchor_ : it means _end of line_. `<<<` is a _here-string_ where `<<` is a _here-doc_ : Similar to here documents: The word after <<< and a newline are passed to the standard input of a command. Syntax: ''command <<< "some sentence"'' (Like ''echo "some sentence" | command'', but without the overhead of the subshell) – Gilles Quénot Mar 22 '18 at 17:12
  • What is the difference between `<` and `<<<` ? – Joe Mar 22 '18 at 22:46
1

You can use multiple quoting styles within a single string. Thus:

$'Constant\r\n\n\r\n'"$bar"

...has the \r\ns parsed with $'...' rules, but the $bar expanded with double-quoting rules (such that the expansion also takes place).

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441