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 / unix / Perguntas / 676608
Accepted
Martian2020
Martian2020
Asked: 2021-11-09 05:45:40 +0800 CST2021-11-09 05:45:40 +0800 CST 2021-11-09 05:45:40 +0800 CST

A negação do bash de -a (o arquivo existe) não altera o resultado, enquanto para ! -e altera o resultado

  • 772

Estou perplexo, mas ainda acho que não entendi Bash de alguma forma.

/$ if [   -e /bin/grep ]; then echo yea; else echo nay ; fi
yea
/$ if [ ! -e /bin/grep ]; then echo yea; else echo nay ; fi
nay
/$ if [   -a /bin/grep ]; then echo yea; else echo nay ; fi
yea
/$ if [ ! -a /bin/grep ]; then echo yea; else echo nay ; fi
yea

Por que a negação !reverte o efeito do -eteste, mas não -ao teste?

Man bash disse:

teste :

3 argumentos

As condições a seguir são aplicadas na ordem listada.

  1. Se o segundo argumento for um dos operadores condicionais binários listados acima em EXPRESSÕES CONDICIONAIS, o resultado da expressão será o resultado do teste binário usando o primeiro e o terceiro argumentos como operandos. Os operadores -ae -osão considerados operadores binários quando há três argumentos.
  2. Se o primeiro argumento for !, o valor será a negação do teste de dois argumentos usando o segundo e o terceiro argumentos.

Expressões Condicionais Bash

Expressões condicionais são usadas pelo [[ comando composto e pelos comandos internos teste[

-a file
Verdadeiro se o arquivo existir.
-b file
True se o arquivo existir e for um arquivo especial de bloco.
-c file
True se o arquivo existir e for um arquivo especial de caracteres.
-d file
True se o arquivo existir e for um diretório.
-e file
Verdadeiro se o arquivo existir.

bash test
  • 2 2 respostas
  • 1603 Views

2 respostas

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2021-11-09T05:56:29+08:002021-11-09T05:56:29+08:00

    -aé um operador unário (para acessível, adicionado para compatibilidade com o shell Korn, mas fora do padrão e agora redundante com -e) e binário (para and, em POSIX (com XSI), mas obsoleto lá).

    Aqui [ ! -a /bin/grep ]invoca o operador binário conforme exigido pelo POSIX. É [ "$a" -a "$b" ]para testar se $anão está vazio e $b não está vazio, aqui com $a== !e $b== /bin/grep. Como ambas as strings não são vazias, ela retorna true .

    Veja também "Os operadores -a e -o são considerados operadores binários quando há três argumentos" no texto que você citou.

    -aestá obsoleto tanto na forma unária quanto na forma binária, a unária porque é substituída por -e, a binária porque cria expressões de teste não confiáveis ​​e ambíguas.

    Para testar a existência do arquivo (embora, na verdade, seja mais um teste se o arquivo é acessível , se stat()seria bem-sucedido no caminho¹), use [ -e filepath ]. Para e duas condições, use &&entre duas invocações de [.

    Para testar se uma string não está vazia, eu pessoalmente prefiro o [ -n "$string" ]formulário ao [ "$string" ]outro.

    Então:

    • teste para a existência do arquivo:

      [ -e "$file" ]   # not [ -a "$file" ]
      [ ! -e "$file" ] # not [ ! -a "$file" ]
      
    • teste para duas strings não vazias:

      [ -n "$a" ] && [ -n "$b" ] # not [ "$a" -a "$b" ]
      [ "$a" ] && [ "$b" ]
      

    Da lógica na especificação POSIX para o utilitário test(aka[ ) :

    As extensões XSI que especificam as primárias binárias -a e -o e os operadores '(' e ')' foram marcadas como obsoletas. (Muitas expressões que as utilizam são definidas de forma ambígua pela gramática, dependendo das expressões específicas que estão sendo avaliadas.) Scripts que usam essas expressões devem ser convertidos para as formas fornecidas abaixo. Embora muitas implementações continuem a oferecer suporte a esses formulários obsoletos, os scripts devem ser extremamente cuidadosos ao lidar com entradas fornecidas pelo usuário que podem ser confundidas com esses e outros primários e operadores.

    e:

    Uma proposta inicial usava o KornShell -a primário (com o mesmo significado), mas isso foi alterado para -e porque havia preocupações sobre a alta probabilidade de humanos confundirem o -a primário com o -a operador binário.

    Os manuais do yash, bosh, GNU coreutilsprotegem contra o uso de binário -a/ -oem suas respectivas [/ testimplementações e zsho manual do ' nunca os documentou², mas muitos outros, incluindo bash(o shell GNU), infelizmente ainda não desencorajam seu uso nem os descontinuam.


    ¹ mais sobre isso nesta minha resposta a um stackoverflow de perguntas e respostas relacionado

    ² a test/ [builtin só foi adicionado ao zsh na versão 2.0.3 em 1991. A [[ ... ]]construção especial, do shell Korn sempre foi preferida lá, e tem sua própria sintaxe where &&e ||são usados ​​para e e ou operadores.

    • 28
  2. Gilles 'SO- stop being evil'
    2021-11-09T05:59:36+08:002021-11-09T05:59:36+08:00

    O Bash analisa [ ! -a WORD ]sendo -ao operador binário que significa “e”, cercado por dois testes de palavra única que são verdadeiros se não estiverem vazios. Assim [ ! -a "" ]é falso e [ ! -a WORD ]verdadeiro se WORDnão for vazio.

    Esta análise está em conformidade com a especificação POSIX (embora estritamente falando, não precisaria, pois unário -anão é especificado pelo POSIX). Aliás, mksh e zsh analisam este caso da mesma maneira, mas ksh93 analisa com unary !seguido de unary -a.

    Para evitar a ambiguidade, não use o -aoperador obsoleto, use o -eoperador padrão, que não possui um operador binário com grafia idêntica. Além disso, para evitar ambiguidade ou erros em casos de canto mais longos, use &&e ||como operadores binários (externo [ … ]ou interno [[ … ]]) em vez do potencialmente ambíguo -a/ -ointerno [ … ].

    • 13

relate perguntas

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

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

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk 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