I would like to cat the contents of a file.txt and use this as part of the --data field in my curl query.

I tried:

curl ... --data '{ "file_content":[" $(cat file.txt) ", ...]}"' ...

but that passes the string $(cat file.txt) to the server rather than interpreting it before sending.

I also tried:

curl ... --data '{ "file_content":[" `cat file.txt` ", ...]}"' ...

Again, the passes the string as it is instead of interpreting it.

  • it may be a typo, but at this point, the part after --data begins a single-quote that is not closed before seeing ..., so that would prevent $ expansion... – Jeff Schaller Jul 21 '15 at 16:02
  • @JeffSchaller Thanks for pointing that out, it was indeed a typo. – Juicy Jul 21 '15 at 16:08
  • so, if you do indeed have single-quotes around the data portion, you'll need to end & restart them around the $(cat file.txt) portion in order for that to expand. As it stands now, the entire data portion is quote off to prevent shell expansion & substition. – Jeff Schaller Jul 21 '15 at 16:20

You probably wouldn't need 3 of those backslashes if you can remove the shell from the equation. Luckily, you can:

{   printf '{ "file_content":["'
    cat file.txt
    printf '", ...]}"'
}|  curl ... --data-binary @-          

Look at man curl. I suggest paying close attention to the differences between --data-ascii (which is what -d means), --data-binary, and --data-urlencoded.


To allow the shell to interpret the $(...) or backticks, you need to stop quoting it:

curl ... --data '{ "file_content":["' $(cat file.txt) '", ...]}"' ...


curl ... --data '{ "file_content":["' `cat file.txt` '", ...]}"' ...
  • Just gave that a try, curl is now complaining that my argument list is too long, that's apparently making it think there is more than one argument in --data (note that file.txt is just a 6mb file of character A) – Juicy Jul 21 '15 at 16:26
  • 1
    Ahh; well, I left spaces on either side of the $(...) business. Remove those and you'll have fewer arguments :) New code would be: ... --data '{ "file_content":["'$(cat file.txt)'", ...]}"' – Jeff Schaller Jul 21 '15 at 16:36
  • 1
    If your file is too big for a command line (it's not curl complaining, it's exec(), via your shell), you'll want curl to read from file. Try curl ... --data @<(printf '%s' '{ "file_content":["'; cat file.txt; printf '", ...]}"') – Toby Speight Jul 21 '15 at 17:03
  • Or, if the header and trailer are constant, put them into files so you can simply curl ... --data @<(cat header file.txt trailer) – Toby Speight Jul 21 '15 at 17:13
  • Forgot to say - that form of process substitution is specific to bash. If your shell is different, there may or may not be an equivalent. – Toby Speight Jul 21 '15 at 17:16

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.