Reputation: 2869
Trying to do the following on contos7 works as I expect:
pod_in_question=$(curl -u uname:password -k very.cluster.com/api/v1/namespaces/default/pods/ | grep -i '"name": "myapp-' | cut -d '"' -f 4)
echo "$pod_in_question"
curl -u uname:password -k -X DELETE "very.cluster.com/api/v1/namespaces/default/pods/${pod_in_question}"
However, trying the same thing on MacOS (10.12.1) yields:
curl: (3) [globbing] bad range in column 92
When I try to curl the last line with a -g
option it substitutes with a malformed name such as: myapp-\\x1b[m\\x1b[Kl1eti\
The echo statement would always execute just fine and show something like myapp-v7454
which I later want to put into the last curl statement. So where are these other characters coming from?
Upvotes: 2
Views: 849
Reputation: 6180
cURL
CLI debugging.This answer is revised after it's been identified that the issue for the OP relates to curl applying color output.
There's a proposed answer which explains clearly what the embedded special characters meant, and instructions to override the grep
behaviour to not output color. Certainly this is a good practise for grep
use in piping. There are however a number of best practises that can help diagnose this or a similar issue with cURL
and ultimately lead to the most robust solution.
Re-creating the problem
echo {'"name": "myapp-7414"'}
to simulate the output from cURL
cURL
commandWe force grep
to output color, since it doesn't normally by default when outputting to a tty.
Recreation:
myvar=$(echo {'"name": "myapp-7414"'} | grep --color=always -i '"name": "myapp-' | cut -d '"' -f 4)
curl "https://www.google.com/${myvar}"
Output:
curl: (3) [globbing] bad range in column 32
First up:
'{}'
are special characters to cURL
, period.
The best practise for URL syntax in cURL
:
If Variable Expansion is required:
-g
switch to disable potential globbing done by cURL
Otherwise:
$variable
as part of a "quoted" url string, instead of ${variable}
Second: In addition to -g
, we add --libcurl /tmp/libcurl
so we can get some insight into what cURL
is seeing.
Recreation with -g
and --libcurl
:
curl -g --libcurl /tmp/libcurl "https://www.google.com/${myvar}"
Output:
<p>Your client has issued a malformed or illegal request <ins>That’s all we know.
Perfect, at least now everything is getting to the server and back! Let's see what cURL
sent out to the server:
cat /tmp/libcurl
Surely enough we find this line: (note the bold part).
curl_easy_setopt(hnd, CURLOPT_URL, "https://www.google.com/myapp-\033[m7414");
So we know that:
cURL
knows not to try glob once we send the -g
switch. That way - If there is an error with the shell variable, we can actually see what it is. We shouldn't be debugging a globbing error if we're not trying to use URL Ranges.--color=always
that we added to simulate the OPs environment.At this point. Since it looks like we're working with JSON data, why not just use a widely available, high performance JSON parsing tool. That has a number of benefits, including:
If we used jq
for example (while we're at it, we don't need the -g
switch because we don't need '{}' for the variable because we're already double "
the URL):
myvar=$(echo {'"name": "myapp-7414"'} | jq -r .name)
curl --libcurl /tmp/libcurl "https://www.google.com/$myvar"
Now we get:
<p>The requested URL
/myapp-7414
was not found on this server. That’s all we know.
Great. It's all working now. It should be obvious that the test URL here being www.google.com
is obviously not going to know was myapp-7414
was.
So we've gone from :
We could also as suggested elsewhere change the grep
output and override it to --color=never
(As I have noted: If grep
has to be used, the --color=never
is a great way to use it as a best practise when piping strings, period.). However, given the portability issues already experienced because of string filtering, and the fact that we are already handed structured data on a plate that can be parsed reliably, the more robust solution would be to do just that, if possible.
Upvotes: 3
Reputation: 63481
The substitution you showed at the last part looks like one of your calls injected ANSI escape sequences. It's possible that grep isn't detecting non-TTY output and is colorizing.
On a terminal that supports ANSI escape sequences, your particular codes might not be visible. The codes ^E[m^E[K
set the screen mode and clear the current line. That's why you thought the echo
command proved your data was correct.
You can examine the raw data with:
echo "$pod_in_question" | hexdump -C
And you should see there are other characters in there which did not appear in your terminal before. When you put these "invisible" codes into the URL, curl tries to encode them and then fails when it encounters a control character (ESC).
The solution is to add the argument --color=never
to your grep call, which will disable colorization.
Upvotes: 0