Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Attempting to shorten a bash script that uses curl to fetch multiple API calls takes something like this:

curl --user $USER:$PASS https://api.example.com/foo -o 'foo.json'
curl --user $USER:$PASS https://api.example.com/bar -o 'bar.json'
curl --user $USER:$PASS https://api.example.com/baz -o 'baz.json'

And use it in this form:

curl --user $USER:$PASS https://api.example.com/{foo,bar,baz} -o '#1.json'

The issue is that curl is fetching foo, bar and baz but is not assigning the output to foo.json, bar.json and baz.json. It is literally creating #1.json and piping output to stdout. Has been tried with single, double, and no quotes, all same result. This is being run inside a bash script, although the curl command behaves the same way when entered directly on the command line. Is this an OS X syntax issue?

share|improve this question
2  
What is it you think the #1 syntax is supposed to do? Where does that come from? Anyway you're almost certainly better off running three different curl invocations in a loop. – Celada yesterday
1  
The #1 syntax is described in the curl man page, if you're curious. – larsks yesterday
    
@larsks yes I see it how, it's part of cURL's pesky built-in globbing. Thanks for educating both myself and the OP. – Celada yesterday
up vote 9 down vote accepted

Your problem is that the {...} expression is also valid shell syntax. For example, run:

echo file/{one,two}

And you get:

file/one file/two

So when you run:

curl --user $USER:$PASS https://api.example.com/{foo,bar,baz} -o '#1.json'

The {foo,bar,baz} is getting interpreted by your shell, and curl actually receives the command line:

  curl --user youruser:secret https://api.example.com/foo https://api.example.com/bar https://api.example.com/baz -o '#1.json'

Since curl doesn't see the {...} expression, you don't get the magical handling for #1. The solution is simply to enclose the URL in single quotes:

curl --user $USER:$PASS 'https://api.example.com/{foo,bar,baz}' -o '#1.json'

The single quotes inhibit any shell expansion of the string.

share|improve this answer
    
Wow, and here I was thinking this question was just based on a misunderstanding of how shell expansion works. Well done. – Wildcard yesterday
    
Brilliant. Always a small detail that's overlooked causing confusing problems. Thanks. – Chase yesterday

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.