Sending a post json with curl get error - linux

Im trying to create a bash script to make github pull requests here its my code:
Gist Code
I get this error:
curl: (6) Could not resolve host: on
curl: (3) [globbing] unmatched close brace/bracket in column 63
{
"message": "Problems parsing JSON",
"documentation_url": "https://developer.github.com/v3"
}
Please help

More/proper quoting:
body=$(printf '{"title":"%s","body":"%s","head":"clamour:%s","base":"%s"}' "$TITLE" "$DESCRIPTION" "$TARGET" "$SOURCE")
curl -H "$auth" -d "$body" "https://api.github.com/repos/clamour/$PROJECT/pulls"
All user-supplied variables must be quoted (unless you know exactly why you want to leave then unquoted).
Enclosing a variable name in ${braces} is not the same as "$quoting".
I find using printf tends to be more clear than mixing double and single quotes with variable interpolation.
Get out of the habit of using ALLCAPS variable names: one day you'll use PATH=... and then wonder why your script is broken

you are using a lot of variables
try to do it like this
BODY="{\"title\":\"$TITLE\",\"body\":\"$DESCRIPTION\",\"head\":\"clamour\":\"$TARGET\",\"base\":\"$SOURCE\"}"
"https://api.github.com/repos/clamour/$PROJECT/pulls"
read also this Difference between single and double quotes in Bash

Related

cURL command works on linux but not windows

Good Day All,
I've got a cURL command here
curl -X POST https://*.com/graph/api/v1/graphql -H 'content-type:application/json' -H 'Authorization:bearer *token*' -d '{"query": "{ assets(query: { searchTerm: \"hello-world-sys-app-v1\" ,type: \"app\"}) { groupId, assetId, version, type } }"}'
This runs as expected on linux and returns like this
{"data":{"assets":[{"groupId":"*","assetId":"hello-world-sys-app-v1","version":"1.0.15-D160-B167-PERF","type":"app"},{"groupId":"*","assetId":"hello-world-sys-app-v1","version":"1.0.15-D157-B115-DEV1","type":"app"}]}}
However when running on windows I get an error like this
The request's Content-Type is not supported. Expected:
application/jsoncurl: (6) Could not resolve host: application
curl: (6) Could not resolve host: bearer
curl: (6) Could not resolve host: dc411cee-c007-4955-ab45-87522b2713ad'
curl: (3) [globbing] nested brace in column 17
I've tried a few solutions i've read on here without luck
https://superuser.com/questions/1291352/curl-command-runs-in-linux-but-not-windows-2008
I've tried a few different combinations of single quotes and double quotes but just getting errors, I've tried using a data file too, but i get similar errors. I have a feeling it is a simple issue, but I can't seem to figure out the syntax.
Any help or ideas would be greatly appreciated!
Thank you
I've suffered the same pain a few days ago, and on Windows the -d must be between double quotes so you've to escape those inside. Something like this (I didn't test it):
-d "{\"query\": \"{ assets(query: { searchTerm: \"hello-world-sys-app-v1\" ,type: \"app\"}) { groupId, assetId, version, type } }\"}"
Om Windows you have Invoke-RestMethod in PowerShell which seems (and only seems) is more accurate. More info here: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-7.1
If you are using something like Git Bash on Windows you may be hitting the problem with forward slash translations.
See https://github.com/bmatzelle/gow/issues/196
I've got it working now on windows, Although I still don't know exactly why its working but I first replaced all the single quotes with double quotes and was still getting errors. but after adding three backslashes I'm able to get a proper response.
curl -X POST "https://*.com/graph/api/v1/graphql" -H "content-type:application/json" -H "Authorization:bearer *" -d "{\"query\": \"{ assets(query: { searchTerm: \\\"hello-world-sys-app-v1\\\" ,type: \\\"app\\\"}) { groupId, assetId, version, type } }\"}"

zsh: no matches found when $ curl -s -X localhost:60702/api/bundle?name=light%20reading | j q '.'

I am working through the Node.js The Right Way book by Jim Wilson. I am currently trying to use a PUSH request to create a new bundle with the specified name.
* curl -X POST http://:/api/bundle?name=
However, when I use the command:
$ curl -s -X POST localhost:60702/api/bundle?name=light%20reading | jq '.'
rather than getting the JSON indicating that a Bundle has been created, I get: zsh: no matches found: localhost:60702/api/bundle?name=light%20reading
The command should be using a POST request to create a new All of my code is bit for bit identical to the code listed in the book. Any ideas?
Can you try
curl -s -X POST 'localhost:3000/api/bundle?name=light%20reading'
i.e wrap the url within '
This seems to be an issue with zsh solved here.
There are several ways to solve this:
You can escape the question mark ? in the url by quoting the url as explained by #huzaifa-saifuddin to avoid zsh treating it as a wildcard character.
As explained here, you can create an alias for curl: alias curl='noglob curl'
As explained here, you can disable to nomatch handling by adding the following to your ~/.zshrc: unsetopt nomatch

How to use quotes in environment variables expansion

In How can I use environment variables in body of a curl PUT request?, I was given the great advise to always use " using doing environment variables.
Say I want do following query:
curl -XPUT http://"${HOST}"/create/"${USER}" -d'{"user":"'"${USER}"'"}'
I enclosed ${USER} between " to ensure that spaces in the user name are possible. I did the same for ${HOST}, although that was strictly not required, since hostnames cannot contain spaces as far as I know.
I am wondering if the following request is equal to the previous request:
curl -XPUT "http://${HOST}/create/${USER}" -d'{"user":"'"${USER}"'"}'
Are they equal? Which one is preferred/most standard?
Yes, they are equal.
I'd prefer
curl -XPUT "http://${HOST}/create/${USER}" -d"{\"user\":\"${USER}\"}"
first because:
it is shorter as #Ryan said in comment
second literal is more readable when in one chunk rather than concatenatig two styles of quotes
some editors will highlight them in more readable way (for example vim )
As you've seen, dealing with quoting conventions in Bash when you have arbitrary data is difficult. However, there's a third way of quoting in cases like this than can make life a lot easier: "here documents".
Using <<TOKEN in a shell command indicates that the lines after the command will be read as the standard input to the command, terminated with TOKEN. Within the here document the usual quoting characters lose their special meaning and are interpreted literally, but variable substitution still happens normally.
To demonstrate, start a netcat "server" to display requests in one terminal with
nc -kl localhost 8888
Now, in another terminal, run this shell script:
name="Alice's Restaurant"
password="quote is ' and doublequote is \\\"."
curl -XPUT http://localhost:8888/create/user --data-binary #- <<EOF
{
"name": "$name",
"password": "$password",
"created": "$(date --iso-8601)"
}
EOF
When a --data argument is given # that requests that curl read the data from the filename specified immediately after the #, and using - as the filename reads from stdin.
Note that here I use --data-binary to make the server's output easier to understand; in production use you'd want to use --data-urlencode or, if the server accepts data in another format, ensure you're setting the Content-type header to that format rather than leaving it at the default application/x-www-form-urlencoded.
When you run the above, you'll see the following in your netcat terminal:
PUT /create/user HTTP/1.1
Host: localhost:8888
User-Agent: curl/7.52.1
Accept: */*
Content-Length: 112
Content-Type: application/x-www-form-urlencoded
{
"name": "Alice's Restaurant",
"password": "quote is ' and doublequote is \".",
"created": "2018-02-20"
}
As you can see, normal quoting characters are not treated specially, you need not do any special quoting on individual shell variables that get expanded within the here document, and you can even use $() to run shell commands whose output will be substituted within the document.
(By the way, I specified the double quote within the password variable as \\\", setting it to \" in the variable after shell interpolation of a double-quoted string, because that's necessary to produce valid JSON. Oh, you can never escape the quoting issues.)

Multiword string as a curl option using Bash

I want to get some data from a HTTP server. What it sends me depends on what I put in a POST request.
What I put in the INPUT_TEXT field is a sequence of words. When I run the following command, I get good looking output.
$ curl http://localhost:59125/process -d INPUT_TEXT="here are some words"
I want a bash script to take some string as a command line argument, and pass it appropriately to curl. The first thing I tried was to put the following in a script:
sentence=$1
command="curl http://localhost:59125/process -d INPUT_TEXT=\"${sentence}\""
$command
I then run the script like so:
$ ./script "here are some words"
But then I get a curl Couldn't resolve host error for each of "are", "some", and "words". It would seem that "here" got correctly treated as the INPUT_TEXT, but the rest of the words were then considered to be hosts, and not part of the option.
So I tried:
command=("curl" "http://localhost:59125/process" "-d" "INPUT_TEXT='$sentence'")
${command[#]}
I got the same output as the first script. I finally got what I wanted with:
result=$(curl http://localhost:59125/process -d INPUT_TEXT="${sentence}")
echo $result
I'm still unsure as to what the distinction is. In the first two cases, when I echoed out the contents of command, I get exactly what I input from the interactive Bash prompt, which had worked fine. What caused the difference?
The following will work:
command=("curl" "http://localhost:59125/process"
"-d" "INPUT_TEXT=$sentence")
"${command[#]}"
That has two changes from yours:
I removed the incorrect quotes around $sentence since you don't want to send quotes to the server (as far as I can see).
I put double-quotes around the use of "${command[#]}". Without the double quotes, the array's elements are concatenated with spaces between them and then the result is word-split. With double quotes, the individual array elements are used as individual words.
The second point is well-explained in the bash FAQ and a bunch of SO answers dealing with quotes.
The important thing to understand is that quotes only quote when a command is parsed. A quote which is a character in a variable is just a character; it is not reinterpreted when the value of the variable expanded. Whitespace in the variable is used for word-splitting if the variable expansion is unquoted; the fact that the whitespace was quoted in the the command which defined the variable is completely irrelevant. In this sense, bash is just the same as any other programming language.

Curl Complex With Bash

Small Note: I removed the http:// from infront each link, because stackoverflow isn't allowing me to post it in original way.
I wrote a script which access to a webpage, to catch a URL and download it. One of the urls makes curl stop working and the whole URLS in the list to the same.
The script works as following:-
PAGE=$(curl -sL pageurl)
FILE_URL=$(echo $PAGE | sed -e 's/^.*<a href=\"\(.*\)\">\(.*\) alt="File" \/><\/a>.*$/\1/')
The FILE_URL VALUE is
URL/files/PartOne - Booke (Coll).pdf
webprod25.megashares.com/index.php?d01=3109985&lccdl=9e8e091ef33dd103&d01go=1&fln=/adobe reader exe.rar
AND SO One for others
When curl tried to catch this url it shows the following error using the debug mode of bash
++ curl -sOL 'webprod37.megashares.com/index.php?d01=3109985&lccdl=9e8e091ef33dd103&d01go=1&fln=/adobe' reader exe.rar fileshare273.depositfiles.com/auth-13023763920cd7ec18a0fdbfa8b62d35-188.165.197.50-43792102-7713641/FS273-7/PageMaker.rar -sOLJg fileshare601.depositfiles.com/auth-1302376689013d421df6c01e7f64c8d2-188.165.197.50-43801594-82379659/FS601-2/Adobe_Flash_Player_v10.3.180.65.2.rar -sOLJg 'webprod37.megashares.com/index.php?d01=de48789&lccdl=9e8e091ef33dd103&d01go=1&fln=/KAZAMIZA.COM.Adobe.Flash' Player-10.3.180.65.Beta-2.JUDGMENT DAY.rar bellatrix.oron.com/spzsttzwytpflwd76j3ne2moukomuhcdxg6llddfztqa2ztd7cplwwp457h3mxuacq3pbxzs/An-Beat - Mentally Insine '(Original' 'Mix).mp3'
curl: option -: is unknown
curl: try 'curl --help' or 'curl --manual' for more information
The quote marks the curl put it itself, I tried to do some workarounds like escaping url but it not works.
The basic problem seems to be that you are using $() expansion for something that looks to me like a multi line value. You should try iterating over each line.
The other problem looks like one of improper quoting of URLs containing spaces. There's a lone dash (-) in "An-Beat - Mentally Insine"
Oh, one more problem: The sed part to catch the href="..." contents only works if there's exactly one href on the line. If there are two or more, your \(.*\) will match everything else up to the last href. You should use something like href="\([^"]*\)", matching "any number of non-doublequotes followed by a doublequote".
Quote your variables as in:
pageurl='the url'
PAGE=$(curl -sL "$pageurl")
FILE_URL=$(echo "$PAGE" | sed -e 's/^.*<a href=\"\(.*\)\">\(.*\) alt="File" \/><\/a>.*$/\1/')
Otherwise, shell expansion will occur. The error "option -: is unknown" comes from the final part:
An-Beat - Mentally Insine
Because you didn't apply quotes to it, it got parsed as arguments, which you can clearly see in the syntax-highlighted code.

Resources