Estou confuso com o uso de colchetes, parênteses, chaves no Bash, bem como a diferença entre as formas duplas ou simples. Existe uma explicação clara?
No Bash, test
e [
são shell shell.
O colchete duplo , que é uma palavra-chave shell, permite funcionalidade adicional. Por exemplo, você pode usar &&
e ||
, em vez de -a
e -o
e há um operador de expressão correspondência normal =~
.
Além disso, em um teste simples, colchetes duplos parecem avaliar muito mais rápido que os únicos.
$ time for ((i=0; i<10000000; i++)); do [[ "$i" = 1000 ]]; done
real 0m24.548s
user 0m24.337s
sys 0m0.036s
$ time for ((i=0; i<10000000; i++)); do [ "$i" = 1000 ]; done
real 0m33.478s
user 0m33.478s
sys 0m0.000s
Os colchetes, além de delimitar um nome de variável, são usados para a 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, as expansões de chaves criam listas de cadeias que são 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}
D H L P T
Observe que os principais recursos de zero e incremento não estavam disponíveis antes do Bash 4.
Obrigado a gboffi por me lembrar sobre expansões de braçadeira.
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 nas variáveis de número inteiro e matriz e inclua espaços em torno dos operadores para facilitar a leitura.
Parênteses únicos também são usados para índices de matriz :
array[4]="hello"
element=${array[index]}
A cinta encaracolada é necessária para (a maioria / todas?) Referências de matriz no lado direito.
O comentário de ephemient me lembrou que os parênteses também são usados para subcamadas. E que eles são usados para criar matrizes.
array=(1 2 3)
echo ${array[1]}
2
:
.$[expression]
; esta é a sintaxe antiga, obsoleta da expressão aritmética para a sintaxe preferida mais recente:$((expression))
bash
criação de seqüências é a criação de seqüências, como periférico mencionado abaixo ( stackoverflow.com/a/8552128/2749397 ) Como eu gostaria de comentar um pouco esse recurso (como você não mencionou ;-) Eu ' m tendo a liberdade de usar a resposta mais votada como veículo ... Dois exemplos de literais de sequência:echo {01..12}
->01 02 03 04 05 06 07 08 09 10 11 12
(observe o zero inicial);echo {C..Q}
->C D E F G H I J K L M N O P Q
. Seu principal uso é em loops, por exemplo,for cnt in {01..12} ; do ... ${cnt} ... ; done
echo {01..12..2}
-> "01 03 05 07 09 11". Obrigado pelo lembrete sobre sequências. Vou adicioná-lo à minha resposta.Um único colchete (
[
) geralmente chama um programa chamado[
;man test
ouman [
para mais informações. Exemplo:O colchete duplo (
[[
) faz a mesma coisa (basicamente) que um colchete único, mas é um bash embutido.Parênteses (
()
) são usados para criar um subshell. Por exemplo:Como você pode ver, o subshell permitiu executar operações sem afetar o ambiente do shell atual.
(a) Chaves (
{}
) são usadas para identificar inequivocamente variáveis. Exemplo:(b) Chaves também são usadas para executar uma sequência de comandos no contexto atual do shell, por exemplo
Existe uma diferença sintática sutil com
( )
, no entanto (consulte a referência do bash ); essencialmente, um ponto e vírgula;
após o último comando dentro de chaves é uma obrigação, e as chaves{
,}
deve ser cercado por espaços.fonte
[
na verdade é um built-in no Bash, mas deve agir como um/bin/[
oposto ao[[
built-in.[[
possui recursos diferentes, como operações mais lógicas e funções de cotação diferentes. Além disso: parênteses únicos também são usados para matrizes, substituição de processos e globs estendidos; parênteses duplos são usados para aritmética; chaves{}
são usadas para agrupamento de comandos ou multidões de tipos de expansão de parâmetro ou expansão de chave ou expansão de sequência. Estou certo de que eu perdi alguns outros usos também ...if [ $VARIABLE == abcdef ]
é um basismo que - embora funcione - provavelmente deve ser evitado; use explicitamente bash (if [[ ...==...]]
) ou deixe claro que você está usando a condicional (if [ "$VARIABLE" = "abcdef" ]
) mais tradicional . Indiscutivelmente, os scripts devem começar o mais simples e portátil possível, até que eles realmente precisem de recursos específicos para o bash (por um motivo ou outro). Mas, em qualquer caso, a intenção deve ser clara; "=" e "==" e "[[" e "[") funcionam de maneira diferente e seu uso deve ser consistente.[ "$var" = ".."]
vez de==
, enquanto em C ela atribuiria em vez de testar (e é uma causa bastante comum de bugs) ... por que não 'ttest
usar==
em vez de=
? Alguém sabe?/usr/bin/[
não é um link simbólico para o/usr/bin/test
e mais: esses programas têm até alguns tamanhos diferentes!)
faz parte dacase
sintaxe da instrução para finalizar uma linha de caso. Não possui parênteses de abertura. Isso me assustou na primeira vez que o vi.Suportes
[1] http://wiki.bash-hackers.org/scripting/obsolete
Aparelho Encaracolado
Parênteses
Parênteses duplos
fonte
$(varname)
não está relacionado à sintaxe do bash. Faz parte da sintaxe Makefile .$(varname)
não tem relação com a sintaxe do bash no seu caso.Eu só queria adicionar estes do TLDP :
fonte
echo ${#ARRAY}
exibe três, por causa do primeiro elemento doARRAY
contém três caracteres, não porque ele contém três elementos! Para imprimir o número de elementos, useecho ${#ARRAY[@]}
.${TEST:-test}
é igual$TEST
se a variávelTEST
existir, caso contrário, simplesmente retorna a string "test". Existe outra versão que faz ainda mais:${TEST:=test}
--- que também é igual a$TEST
se TEST existe, mas sempre que não existe, ela cria a variávelTEST
e atribui um valor "test" e também se torna o valor de toda a expressão.A diferença entre teste , [ e [[ é explicado em grandes detalhes no BashFAQ .
E a conclusão:
fonte
Parênteses na definição de função
Parênteses
()
estão sendo usados na definição de função:Essa é a razão pela qual você precisa escapar parênteses, mesmo nos parâmetros de comando:
fonte
unset -f echo
. Vejahelp unset
.fonte