Como usar colchetes duplos ou únicos, parênteses, chaves

Estou confuso com o uso de colchetes, parênteses, chaves no Bash, bem como a diferença entre suas formas dupla ou única. Existe uma explicação clara?

No Bash, test e [ são construídos.

O suporte duplo permite funcionalidade adicional. Por exemplo, você pode usar && e || em vez de -a e -o e há uma expressão regular correspondente operator =~ .

As chaves, além de delimitar um nome de variável, são usadas para expansão de parâmetros, para que você possa fazer coisas como:

  • Truncar o conteúdo de uma variável

    $ var="abcde"; echo ${var%d*}
    abc

  • Faça substituições semelhantes a sed

    $ var="abcde"; echo ${var/de/12}
    abc12

  • Use um valor padrão

    $ default="hello"; unset var; echo ${var:-$default}
    hello

  • e vários mais

Além disso, expansões de chaves criam listas de strings que são tipicamente iteradas em loops:

 $ echo f{oo,ee,a}d food feed fad $ mv error.log{,.OLD} (error.log is renamed to error.log.OLD because the brace expression expands to "mv error.log error.log.OLD") $ for num in {000..2}; do echo "$num"; done 000 001 002 $ echo {00..8..2} 00 02 04 06 08 $ echo {D..T..4} DHLPT 

Observe que os principais resources de zero e incremento não estavam disponíveis antes do Bash 4.

Obrigado ao gboffi por me lembrar das expansões de chaves.

Parênteses duplos são usados ​​para operações aritméticas :

 ((a++)) ((meaning = 42)) for ((i=0; i<10; i++)) echo $((a + b + (14 * c))) 

e eles permitem que você omita os sinais de dólar em variables ​​inteiras e de matriz e inclua espaços em torno de operadores para legibilidade.

Parênteses únicos também são usados ​​para índices de array :

 array[4]="hello" element=${array[index]} 

A chave Curly é necessária para referências de matriz (a maioria / todas?) No lado direito.

O comentário do ephemient me lembrou que os parênteses também são usados ​​para subshells. E que eles são usados ​​para criar matrizes.

 array=(1 2 3) echo ${array[1]} 2 
  1. Um único colchete ( [ ) geralmente chama um programa chamado [ ; man test ou man [ para mais informações. Exemplo:

     $ VARIABLE=abcdef $ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi yes 
  2. O colchete duplo ( [[ ) faz a mesma coisa (basicamente) que um único colchete, mas é um bash embutido.

     $ VARIABLE=abcdef $ if [[ $VARIABLE == 123456 ]] ; then echo yes ; else echo no ; fi no 
  3. Parênteses ( () ) são usados ​​para criar um subnível. Por exemplo:

     $ pwd /home/user $ (cd /tmp; pwd) /tmp $ pwd /home/user 

    Como você pode ver, o subshell permite que você realize operações sem afetar o ambiente do shell atual.

4a. Chaves ( {} ) são usadas para identificar inequivocamente variables. Exemplo:

  $ VARIABLE=abcdef $ echo Variable: $VARIABLE Variable: abcdef $ echo Variable: $VARIABLE123456 Variable: $ echo Variable: ${VARIABLE}123456 Variable: abcdef123456 

4b. As chaves também são usadas para executar uma seqüência de comandos no contexto da shell atual , por exemplo

  $ { date; top -b -n1 | head ; } >logfile # 'date' and 'top' output are concatenated, # could be useful sometimes to hunt for a top loader ) $ { date; make 2>&1; date; } | tee logfile # now we can calculate the duration of a build from the logfile 

Há uma diferença sintática sutil com ( ) , embora (consulte a referência bash ); essencialmente, um ponto ; vírgula ; após o último comando entre chaves é uma obrigação, e as chaves { , } devem ser cercadas por espaços.

Colchetes

 if [ CONDITION ] Test construct if [[ CONDITION ]] Extended test construct Array[1]=element1 Array initialization [az] Range of characters within a Regular Expression $[ expression ] A non-standard & obsolete version of $(( expression )) [1] 

[1] http://wiki.bash-hackers.org/scripting/obsolete

Cintas Encaracoladas

 ${variable} Parameter substitution ${!variable} Indirect variable reference { command1; command2; . . . commandN; } Block of code {string1,string2,string3,...} Brace expansion {a..z} Extended brace expansion {} Text replacement, after find and xargs 

Parênteses

 ( command1; command2 ) Command group executed within a subshell Array=(element1 element2 element3) Array initialization result=$(COMMAND) Command substitution, new style >(COMMAND) Process substitution < (COMMAND) Process substitution 

Parênteses duplos

 (( var = 78 )) Integer arithmetic var=$(( 20 + 5 )) Integer arithmetic, with variable assignment (( var++ )) C-style variable increment (( var-- )) C-style variable decrement (( var0 = var1<98?9:21 )) C-style ternary operation 

Eu só queria adicionar isso do TLDP :

 ~:$ echo $SHELL /bin/bash ~:$ echo ${#SHELL} 9 ~:$ ARRAY=(one two three) ~:$ echo ${#ARRAY} 3 ~:$ echo ${TEST:-test} test ~:$ echo $TEST ~:$ export TEST=a_string ~:$ echo ${TEST:-test} a_string ~:$ echo ${TEST2:-$TEST} a_string ~:$ echo $TEST2 ~:$ echo ${TEST2:=$TEST} a_string ~:$ echo $TEST2 a_string ~:$ export STRING="thisisaverylongname" ~:$ echo ${STRING:4} isaverylongname ~:$ echo ${STRING:6:5} avery ~:$ echo ${ARRAY[*]} one two one three one four ~:$ echo ${ARRAY[*]#one} two three four ~:$ echo ${ARRAY[*]#t} one wo one hree one four ~:$ echo ${ARRAY[*]#t*} one wo one hree one four ~:$ echo ${ARRAY[*]##t*} one one one four ~:$ echo $STRING thisisaverylongname ~:$ echo ${STRING%name} thisisaverylong ~:$ echo ${STRING/name/string} thisisaverylongstring 

A diferença entre o teste , [ e [[ é explicado em grandes detalhes no BashFAQ .

Para encurtar a história: o teste implementa a syntax antiga e portátil do comando. Em quase todas as shells (as mais antigas são as exceções), [é sinônimo de teste (mas requer um argumento final de]). Embora todas as shells modernas tenham implementações embutidas de [, normalmente ainda há um executável externo com esse nome, por exemplo, / bin / [.

[[é uma nova versão melhorada dele, que é uma palavra-chave, não um programa. Isso tem efeitos benéficos na facilidade de uso, como mostrado abaixo. [entendido por KornShell e BASH (por exemplo, 2.03), mas não pelo POSIX ou BourneShell mais antigo.

E a conclusão:

Quando o novo comando de teste [[deve ser usado e quando o antigo [? Se a portabilidade para o BourneShell é uma preocupação, a syntax antiga deve ser usada. Se, por outro lado, o script requer BASH ou KornShell, a nova syntax é muito mais flexível.

Parênteses na definição de function

Parênteses () estão sendo usados ​​na definição da function:

 function_name () { command1 ; command2 ; } 

Essa é a razão pela qual você tem que escaping dos parênteses, mesmo nos parâmetros de comando:

 $ echo ( bash: syntax error near unexpected token `newline' $ echo \( ( $ echo () { command echo The command echo was redefined. ; } $ echo anything The command echo was redefined.