For instance, this works:

$ curl -s -X GET "http://api-int.abc.com/api/{,,,}ukulele/v1/health"

This runs 4 curl commands, which is what I want.

Meanwhile ping won't use brace expansion:

$ ping {google,yahoo,microsoft}.com
usage: ping [-AaDdfnoQqRrv] [-b boundif] [-c count] [-G sweepmaxsize]

But touch will:

$ touch .temp/{a,b,c}.txt

Creates three files.

How would I know from the man page for these commands which ones can use brace expansion?


The first thing to understand is that some commands allow multiple arguments and some do not. While touch allows multiple arguments, ping does not. In the case of ping, the braces are expanding to multiple and calling ping with multiple arguments, which ping will not do. A for loop is a better solution in this case. Also, the braces in curl are a special case (see below).

The answer to "which commands can use brace expansion" is all and none. The brace expansion is done by the shell, before passing the expanded output to the command. In other words, the command being launched is completely irrelevant. The expansion of foo{bar,baz} to foobar foobaz is done by the shell before launching the command and passing the expanded string as parameters to it.

However, brace expansion does not occur inside quotes. In other words, both "{,,,}" and "{a,b,c}" remain as strings and are not expanded:

$ echo "{,,,}"
$ echo "{a,b,c}"

To get expansion to work, you should remove the quotes:

$ echo {,,,}  ## this expands to a blank string, so this is what is printed

$ echo {a,b,c}
a b c

This is documented in the relevant section of man bash (emphasis mine):

Brace expansion is performed before any other expansions, and any characters special to other expansions are preserved in the result. It is strictly textual. Bash does not apply any syntactic interpretation to the context of the expansion or the text between the braces.

A correctly-formed brace expansion must contain unquoted opening and closing braces, and at least one unquoted comma or a valid sequence expression.

Now, the reason you are confused is that curl actually has its own parser and that also handles brace expansion. This is done independently of the shell and is explained in man curl:

You can specify multiple URLs or parts of URLs by writing part sets within braces as in:


So, any command can work with brace expansion since it isn't actually the command working with it, but the shell that expands the expression in the braces before calling the command. Curl is confusing because it has its own, similar feature.

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.