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 / 420718
Accepted
hudac
hudac
Asked: 2018-01-31 08:55:50 +0800 CST2018-01-31 08:55:50 +0800 CST 2018-01-31 08:55:50 +0800 CST

"foo && bar || baz" no bash se comportando de maneira diferente de "if foo; then bar; else baz" [duplicado]

  • 772
Esta pergunta já tem respostas aqui :
Precedência dos operadores lógicos do shell &&, || (5 respostas)
Fechado há 4 anos .

Eu pensei

[ 1 -eq $1 ] && echo "yes" || echo "no"

Age como

if [ 1 -eq $1 ]; then
    echo "yes"
else
    echo "no"
fi

Mas, quando eu executo este script ( nocmdé um comando inexistente)

#!/bin/bash

[ 1 -eq $1 ] && nocmd "yes" || echo "no"

Eu recebo uma saída estranha para o parâmetro '1':

me@ubuntu:/tmp$ ./ddd.sh 0
no
me@ubuntu:/tmp$ ./ddd.sh 1
./sh.sh: line 3: nocmd: command not found
no

Parece que ele age como:

if [ 1 -eq $1 ]; then
    nocmd "yes"
    if [ $? -ne 0 ]; then
        echo "no"
    fi
else
    echo "no"
fi

Está bom? Estou esquecendo de algo?

bash shell-script
  • 3 3 respostas
  • 1694 Views

3 respostas

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2018-01-31T09:01:47+08:002018-01-31T09:01:47+08:00

    Exceto pelo status geral de saída, ele age como:

    if
      ! { 
        [ 1 -eq $1 ] && nocmd "yes"
      }
    then
      echo no
    fi
    

    Dentro:

    A || B
    

    Bé executado se Afalhar. Isso é um operador OU.

    No seu caso, Aé [ 1 -eq $1 ] && nocmd "yes"onde nocmdé executado se [for bem-sucedido (um operador AND), caso em que o status de saída Aserá o de nocmd. Em outras palavras echo no, será executado se [ou nocmd "yes"falhar (lembrando que nocmdsó é executado se for bem- [sucedido).

    Esses x && y || zsão hacks sujos. É melhor evitá-los exatamente por esse motivo. Use uma construção if// se quiser uma lógica if/then/else then. elseUse x && y || zapenas se você quiser , a menos que zambos tenham sucesso.xy

    Mesmo em:

    cmd && echo OK || echo >&2 KO
    

    O echo OKpode falhar em algumas condições patológicas (como stdout indo para um arquivo em um sistema de arquivos completo) e echo >&2 KOpode acabar sendo executado também.

    $ bash -c 'true && echo OK || echo KO >&2' > /dev/full
    bash: line 0: echo: write error: No space left on device
    KO
    
    • 20
  2. Weijun Zhou
    2018-01-31T09:01:30+08:002018-01-31T09:01:30+08:00

    Bem, o que realmente acontece é isso (e é assim que &&funciona ||)

    test 1 -eq $1
    ret=$?
    if [ $ret -eq 0 ]; then
        nocmd "yes"
        ret=$?
    fi
    if [ $ret -ne 0 ]; then
        echo "no"
    fi
    

    No seu caso, se $1não for igual a 1, ou não for um número válido , então você tem um diferente de zero $?, e o primeiro ifé ignorado e o segundo ifimprime "não". Se $1igual 1a , então nocmd "yes"é executado, retornando um diferente de zero $?e "não" também é repetido.

    • 5
  3. Sergiy Kolodyazhnyy
    2018-01-31T09:20:43+08:002018-01-31T09:20:43+08:00

    O que está faltando é isso &&e ||operar no status de saída dos comandos à esquerda deles - associatividade à esquerda. Você tem aqui some group of commands || echo "no", e noserá repetido se e somente se esse grupo de comandos retornar o status de saída sem sucesso.

    O que é esse grupo de comandos? No primeiro caso você tem [ 1 -eq "$1" ] && echo "yes". Se [parte falhou, isso seria contado como status de saída de falha para [ 1 -eq "$1" ] && echo "yes", portanto, você echo "no"executaria. Também por causa da associatividade à esquerda, quando "$ 1" é 1, o [ 1 -eq $1 ]retorno é sucesso, então vamos nocmdexecutar o que não existe e o shell retornará o status de saída de erro, todo o grupo terá status de saída de falha, portanto "não" é ecoado .

    Por outro lado, em sua declaração if

    if [ 1 -eq $1 ]; then
        echo "yes"
    else
        echo "no"
    fi
    

    qual rota tomar depende apenas do status de saída da [parte. Em [ 1 -eq "$1" ] && echo "Yes" || echo "no"eco também desempenha um papel sobre se é echo "no"executado ou não.

    Seu segundo exemplo de instrução if também é diferente

    if [ 1 -eq $1 ]; then
        nocmd "yes"
        if [ $? -ne 0 ]; then
            echo "no"
        fi
    else
        echo "no"
    fi
    

    O echo "no"depois else não depende do que acontece nocmdcomo no encadeamento de operadores lógicos. Claro que você ainda faz a echo "no"parte depois de fazer nocmd, mas aqui seu status de saída não é agrupado com toda a ifparte à qual pertence.

    • 3

relate perguntas

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

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

  • MySQL Select com função IN () com array bash

  • 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

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

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 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

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 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
    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
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +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
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +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