AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / server / Perguntas / 52034
Accepted
0x89
0x89
Asked: 2009-08-10 13:11:51 +0800 CST2009-08-10 13:11:51 +0800 CST 2009-08-10 13:11:51 +0800 CST

Qual é a diferença entre colchetes duplos e simples no bash?

  • 772

Eu só queria saber qual exatamente a diferença entre

[[ $STRING != foo ]]

e

[ $STRING != foo ]

é, além de que o último é compatível com POSIX, encontrado em sh e o primeiro é uma extensão encontrada no bash.

scripting bash shell posix
  • 5 5 respostas
  • 260914 Views

5 respostas

  • Voted
  1. Best Answer
    Kyle Brandt
    2009-08-10T13:56:00+08:002009-08-10T13:56:00+08:00

    Existem várias diferenças. Na minha opinião, alguns dos mais importantes são:

    1. [é um embutido no Bash e em muitos outros shells modernos. O builtin [é semelhante ao testrequisito adicional de um fechamento ]. Os builtins [e testimitam a funcionalidade /bin/[e /bin/testjunto com suas limitações para que os scripts sejam compatíveis com versões anteriores. Os executáveis ​​originais ainda existem principalmente para conformidade com POSIX e compatibilidade com versões anteriores. A execução do comando type [no Bash indica que [é interpretado como interno por padrão. (Nota: which [apenas procura executáveis ​​no PATH e é equivalente a type -P [. Você pode executar type --helppara obter detalhes)
    2. [[não é tão compatível, não funcionará necessariamente com o que quer que seja /bin/sh. Assim [[é a opção mais moderna Bash / Zsh / Ksh.
    3. Como [[está embutido no shell e não possui requisitos herdados, você não precisa se preocupar com a divisão de palavras com base na variável IFS para atrapalhar as variáveis ​​que avaliam uma string com espaços. Portanto, você realmente não precisa colocar a variável entre aspas duplas.

    Na maior parte, o resto é apenas uma sintaxe melhor. Para ver mais diferenças, recomendo este link para uma resposta de perguntas frequentes: Qual é a diferença entre teste, [ e [[ ? . Na verdade, se você leva a sério os scripts bash, recomendo a leitura de todo o wiki , incluindo o FAQ, Pitfalls e Guide. A seção de teste da seção de guia também explica essas diferenças e por que o(s) autor(es) acham que [[é uma escolha melhor se você não precisa se preocupar em ser tão portátil. Os principais motivos são:

    1. Você não precisa se preocupar em citar o lado esquerdo do teste para que ele seja lido como uma variável.
    2. Você não precisa escapar menor que e maior que < >com barras invertidas para que eles não sejam avaliados como redirecionamento de entrada, o que pode realmente atrapalhar algumas coisas substituindo arquivos. Isso novamente volta a [[ser um builtin. Se [ (teste) for um programa externo, o shell teria que fazer uma exceção na maneira como avalia <e >apenas se /bin/testestiver sendo chamado, o que não faria muito sentido.
    • 375
  2. abhiomkar
    2010-12-30T11:42:25+08:002010-12-30T11:42:25+08:00

    Resumidamente:

    [é um bash embutido

    [[ ]] são palavras- chave bash

    Palavras-chave: as palavras- chave são como builtins, mas a principal diferença é que regras especiais de análise se aplicam a elas. Por exemplo, [ é um bash embutido, enquanto [[ é uma palavra-chave do bash. Ambos são usados ​​para testar coisas, mas como [[ é uma palavra-chave em vez de um built-in, ele se beneficia de algumas regras especiais de análise que tornam muito mais fácil:

      $ [ a < b ]
     -bash: b: No such file or directory
      $ [[ a < b ]]
    

    O primeiro exemplo retorna um erro porque o bash tenta redirecionar o arquivo b para o comando [ a ]. O segundo exemplo realmente faz o que você espera. O caractere < não tem mais seu significado especial de operador de Redirecionamento de Arquivo.

    Fonte: http://mywiki.wooledge.org/BashGuide/CommandsAndArguments

    • 159
  3. Ciro Santilli OurBigBook.com
    2015-07-13T02:22:47+08:002015-07-13T02:22:47+08:00

    Diferenças de comportamento

    Algumas diferenças no Bash 4.3.11:

    • Extensão POSIX vs Bash:

      • [ é POSIX
      • [[ é uma extensão Bash inspirada no shell Korn
    • comando regular vs magia

      • [é apenas um comando regular com um nome estranho.

        ]é apenas o último argumento de [.

      O Ubuntu 16.04 na verdade tem um executável para ele /usr/bin/[fornecido por coreutils , mas a versão interna do bash tem precedência.

      Nada é alterado na maneira como o Bash analisa o comando.

      Em particular, <é o redirecionamento &&e ||concatena vários comandos, ( )gera subshells, a menos que seja escapado por \, e a expansão de palavras acontece como de costume.

      • [[ X ]]é uma construção única que faz Xser analisada magicamente. <, &&, ||e ()são tratados especialmente, e as regras de divisão de palavras são diferentes.

        Há também outras diferenças como =e =~.

      Em Bashese: [é um comando interno e [[é uma palavra-chave: https://askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and-shell-keyword

    • <

      • [[ a < b ]]: comparação lexicográfica
      • [ a \< b ]: O mesmo que acima. \necessário ou então redireciona como para qualquer outro comando. Extensão Bash.
      • expr x"$x" \< x"$y" > /dev/nullou [ "$(expr x"$x" \< x"$y")" = 1 ]: equivalentes POSIX, consulte: https://stackoverflow.com/questions/21294867/how-to-test-strings-for-lexicographic-less-than-or-equal-in-bash/52707989#52707989
    • &&e||

      • [[ a = a && b = b ]]: verdadeiro, lógico e
      • [ a = a && b = b ]: erro de sintaxe, &&analisado como um separador de comando ANDcmd1 && cmd2
      • [ a = a ] && [ b = b ]: POSIX equivalente confiável
      • [ a = a -a b = b ]: quase equivalente, mas obsoleto pelo POSIX porque é insano e falha para alguns valores de aou bsemelhantes !ou (que seriam interpretados como operações lógicas
    • (

      • [[ (a = a || a = b) && a = b ]]: falso. Sem ( ), seria verdadeiro porque [[ && ]]tem maior precedência do que[[ || ]]
      • [ ( a = a ) ]: erro de sintaxe, ()é interpretado como um subshell
      • [ \( a = a -o a = b \) -a a = b ]: equivalente, mas (), -a, e -osão obsoletos pelo POSIX. Sem \( \)seria verdade porque -atem maior precedência do que-o
      • { [ a = a ] || [ a = b ]; } && [ a = b ]equivalente POSIX não obsoleto. Neste caso em particular, no entanto, poderíamos ter escrito apenas: [ a = a ] || [ a = b ] && [ a = b ]porque os operadores ||e shell têm precedência igual ao contrário de e e , e&&[[ || ]][[ && ]]-o-a[
    • divisão de palavras e geração de nome de arquivo em expansões (split+glob)

      • x='a b'; [[ $x = 'a b' ]]: true, as aspas não são necessárias
      • x='a b'; [ $x = 'a b' ]: erro de sintaxe, expande para[ a b = 'a b' ]
      • x='*'; [ $x = 'a b' ]: erro de sintaxe se houver mais de um arquivo no diretório atual.
      • x='a b'; [ "$x" = 'a b' ]: equivalente POSIX
    • =

      • [[ ab = a? ]]: true, porque faz correspondência de padrões ( * ? [são mágicos). Não expande glob para arquivos no diretório atual.
      • [ ab = a? ]: a?globo se expande. Portanto, pode ser verdadeiro ou falso dependendo dos arquivos no diretório atual.
      • [ ab = a\? ]: false, não expansão glob
      • =e ==são os mesmos em ambos [e [[, mas ==é uma extensão Bash.
      • case ab in (a?) echo match; esac: equivalente POSIX
      • [[ ab =~ 'ab?' ]]: false, perde a magia ''no Bash 3.2 e superior e a compatibilidade fornecida para o bash 3.1 não está ativada (como com BASH_COMPAT=3.1)
      • [[ ab? =~ 'ab?' ]]: verdadeiro
    • =~

      • [[ ab =~ ab? ]]: true, correspondência de expressão regular estendida? POSIX, não expande glob
      • [ a =~ a ]: erro de sintaxe. Nenhum equivalente de bash.
      • printf 'ab\n' | grep -Eq 'ab?': equivalente POSIX (somente dados de linha única)
      • awk 'BEGIN{exit !(ARGV[1] ~ ARGV[2])}' ab 'ab?': equivalente POSIX.

    Recomendação: use sempre[]

    Existem equivalentes POSIX para cada [[ ]]construção que eu vi.

    Se você usa [[ ]]você:

    • perder a portabilidade
    • forçar o leitor a aprender os meandros de outra extensão bash. [é apenas um comando regular com um nome estranho, nenhuma semântica especial está envolvida.

    Agradecimentos a Stéphane Chazelas por importantes correções e acréscimos.

    • 102
  4. Premraj
    2016-02-08T19:15:42+08:002016-02-08T19:15:42+08:00

    Single Bracket , ou seja, []é compatível com shell POSIX para incluir uma expressão condicional.

    Double Brackets , ou seja, [[]]é uma versão aprimorada (ou extensão) da versão POSIX padrão, isso é suportado pelo bash e outros shells (zsh, ksh).

    No bash, para comparação numérica, usamos eq, e ne, com colchetes duplos para comparação, podemos usar , e literalmente .ltgt==!=<,>

    • [é um sinônimo para comando de teste. Mesmo que esteja embutido no shell, ele cria um novo processo.
    • [[é uma nova versão melhorada dele, que é uma palavra-chave, não um programa.

    por exemplo:

    [ var1 lt var2] #works
    [ var1 < var2] #error: var2 No such file or directory 
    [ var1 \< var2] #works with escape
    [[ var1 < var2]] #works
    
    • 18
  5. womble
    2009-08-10T13:17:58+08:002009-08-10T13:17:58+08:00

    Com base em uma leitura rápida das seções relevantes da página de manual, a principal diferença parece ser que os operadores ==and !=correspondem a um padrão, em vez de uma string literal, e também que existe o =~operador de comparação regex.

    • 9

relate perguntas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Ping uma porta específica

    • 18 respostas
  • Marko Smith

    Qual porta o SFTP usa?

    • 6 respostas
  • Marko Smith

    Resolver o nome do host do endereço IP

    • 8 respostas
  • Marko Smith

    Como posso classificar a saída du -h por tamanho

    • 30 respostas
  • Marko Smith

    Linha de comando para listar usuários em um grupo do Windows Active Directory?

    • 9 respostas
  • Marko Smith

    Qual é o utilitário de linha de comando no Windows para fazer uma pesquisa reversa de DNS?

    • 14 respostas
  • Marko Smith

    Como verificar se uma porta está bloqueada em uma máquina Windows?

    • 4 respostas
  • Marko Smith

    Qual porta devo abrir para permitir a área de trabalho remota?

    • 9 respostas
  • Marko Smith

    O que é um arquivo Pem e como ele difere de outros formatos de arquivo de chave gerada pelo OpenSSL?

    • 3 respostas
  • Marko Smith

    Como determinar se uma variável bash está vazia?

    • 15 respostas
  • Martin Hope
    Davie Ping uma porta específica 2009-10-09 01:57:50 +0800 CST
  • Martin Hope
    MikeN No Nginx, como posso reescrever todas as solicitações http para https mantendo o subdomínio? 2009-09-22 06:04:43 +0800 CST
  • Martin Hope
    Tom Feiner Como posso classificar a saída du -h por tamanho 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    0x89 Qual é a diferença entre colchetes duplos e simples no bash? 2009-08-10 13:11:51 +0800 CST
  • Martin Hope
    kch Como altero a senha da minha chave privada? 2009-08-06 21:37:57 +0800 CST
  • Martin Hope
    Kyle Brandt Como funciona a sub-rede IPv4? 2009-08-05 06:05:31 +0800 CST
  • Martin Hope
    Noah Goodrich O que é um arquivo Pem e como ele difere de outros formatos de arquivo de chave gerada pelo OpenSSL? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent Como determinar se uma variável bash está vazia? 2009-05-13 09:54:48 +0800 CST

Hot tag

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve