Como posso saber quais comandos usarão a expansão de chaves e quais não usarão?

3

Por exemplo, isso funciona:

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

Isso executa 4 comandos curl, que é o que eu quero.

Entretanto, ping não utilizará expansão de chaves:

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

Mas o toque vai:

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

Cria três arquivos.

Como eu saberia da página man desses comandos quais deles podem usar a expansão de chaves?

    
por jcollum 13.03.2017 / 16:31

1 resposta

5

A primeira coisa a entender é que alguns comandos permitem vários argumentos e outros não. Enquanto touch permite vários argumentos, ping não. No caso de ping , as chaves estão se expandindo para múltiplos e chamando ping com vários argumentos, o que ping não fará. Um loop for é uma solução melhor neste caso. Além disso, as chaves em curl são um caso especial (veja abaixo).

A resposta para "quais comandos podem usar a expansão de chaves" é toda e nenhuma. A expansão da chave é feita pelo shell, antes de passar a saída expandida para o comando. Em outras palavras, o comando que está sendo lançado é completamente irrelevante. A expansão de foo{bar,baz} to foobar foobaz é feita pelo shell antes de lançar o comando e passar a string expandida como parâmetros para ele.

No entanto, a expansão de chaves não ocorre dentro de cotações. Em outras palavras, "{,,,}" e "{a,b,c}" permanecem como strings e não são expandidos:

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

Para que a expansão funcione, você deve remover as aspas:

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

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

Isso está documentado na seção relevante de man bash (ênfase minha):

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.

Agora, o motivo pelo qual você está confuso é que curl tem seu próprio analisador e também trata da expansão de chaves. Isso é feito independentemente do shell e é explicado em man curl :

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

 http://site.{one,two,three}.com

Assim, qualquer comando pode trabalhar com expansão de contraventamento, já que na verdade não é o comando que está trabalhando com ele, mas o shell que expande a expressão nas chaves antes de chamar o comando. Curl é confuso porque tem seu próprio recurso similar.

    
por 13.03.2017 / 16:43