Como condicionalmente fazer algo se um comando tiver sucesso ou falhar

216

Como posso fazer algo assim em bash?

if "'command' returns any error";
then
    echo "Returned an error"
else
    echo "Proceed..."
fi
    
por Michael Mrozek 16.10.2011 / 23:25

10 respostas

264

Isso é exatamente o que a declaração if do bash faz:

if command ; then
    echo "Command succeeded"
else
    echo "Command failed"
fi

Adicionando informações dos comentários: você não precisa usar a sintaxe [ ... ] neste caso. [ é um comando, quase equivalente a test . É provavelmente o comando mais comum para usar em um if , o que pode levar à suposição de que é parte da sintaxe do shell. Mas se você quiser testar se um comando foi bem-sucedido ou não, use o próprio comando diretamente com if , como mostrado acima.

    
por 16.10.2011 / 23:50
94

Para pequenas coisas que você quer que aconteçam se um comando shell funcionar, você pode usar o && construct:

rm -rf somedir && trace_output "Removed the directory"

Da mesma forma, para pequenas coisas que você quer que aconteçam quando um comando shell falha, você pode usar || :

rm -rf somedir || exit_on_error "Failed to remove the directory"

Ou ambos

rm -rf somedir && trace_output "Removed the directory" || exit_on_error "Failed to remove the directory"

Provavelmente não é aconselhável fazer muito com essas construções, mas elas podem ocasionalmente tornar o fluxo de controle muito mais claro.

    
por 17.10.2011 / 02:34
79

Verifique o valor de $? , que contém o resultado da execução do comando / função mais recente:

#!/bin/bash

echo "this will work"
RESULT=$?
if [ $RESULT -eq 0 ]; then
  echo success
else
  echo failed
fi

if [ $RESULT == 0 ]; then
  echo success 2
else
  echo failed 2
fi
    
por 16.10.2011 / 23:34
38

Isso funcionou para mim:

command && echo "OK" || echo "NOK"

se command for bem-sucedido, então echo "OK" será executado e, como é bem-sucedido, a execução será interrompida. Caso contrário, && será ignorado e echo "NOK" será executado.

    
por 17.09.2013 / 08:36
5

Deve-se observar que o tipo de abordagem if...then...fi e && / || lida com o status de saída retornado pelo comando que queremos testar (0 no sucesso); no entanto, alguns comandos não retornam um status de saída diferente de zero se o comando falhar ou não puder lidar com a entrada. Isso significa que as abordagens usuais if e && / || não funcionarão para esses comandos específicos.

Por exemplo, no Linux GNU file ainda sai com 0 se recebeu um arquivo não existente como argumento e find não conseguiu localizar o usuário do arquivo especificado.

$ find . -name "not_existing_file"                                          
$ echo $?
0
$ file ./not_existing_file                                                  
./not_existing_file: cannot open './not_existing_file' (No such file or directory)
$ echo $?
0

Nesses casos, uma maneira potencial de lidarmos com a situação é lendo stderr / stdin messages, por exemplo, aqueles que retornaram pelo comando file ou analisam a saída do comando como em find . Para esse propósito, case declaração poderia ser usada.

$ file ./doesntexist  | while IFS= read -r output; do                                                                                                                  
> case "$output" in 
> *"No such file or directory"*) printf "%s\n" "This will show up if failed";;
> *) printf "%s\n" "This will show up if succeeded" ;;
> esac
> done
This will show up if failed

$ find . -name "doesn'texist" | if ! read IFS= out; then echo "File not found"; fi                                                                                     
File not found
    
por 12.11.2017 / 19:57
2
#!/bin/bash

if command-1 ; then
   echo "command-1 succeeded and now running from this block command-2"
   command-2
else
   echo "command-1 failed and now running from this block command-3"
   command-3
fi
    
por 22.11.2017 / 17:04
1

Você pode fazer isso:

if ($( ping 4.4.4.4 -c1 > /dev/null )) ; then
  echo "ping response succsess!!!"
fi
    
por 01.04.2015 / 17:19
1

Como observado em outras partes deste tópico, a pergunta original basicamente responde a si mesma. Aqui está uma ilustração mostrando que if condições também podem ser aninhadas.

Este exemplo usa if para verificar se existe um arquivo e se é um arquivo normal. Se essas condições forem verdadeiras, verifique se possui um tamanho maior que 0.

#!/bin/bash

echo "Which error log are you checking today? "
read answer

if [ -f /opt/logs/$answer*.errors ]
    then
        if [ -s /opt/logs/$answer*.errors ]
            then
                echo "Content is present in the $answer error log file."
            else
                echo "No errors are present in the $answer error log file."
        fi
    else
        echo "$answer does not have an error log at this time."
fi
    
por 24.12.2015 / 03:23
1

A maior propensão a erros que eu pude encontrar foi:

  • Primeiro, pegue o valor. Suponha que você faça algo como:

RR=$?

Agora, não apenas para essa situação, mas para outros que você possa enfrentar, considere:

variável definida:

$ AA=1 ; if (( "10#0${AA}" == 1 )) ; then echo yes ; else echo no ; fi

Resposta: sim

$ AA=1 ; if (( "10#0${AA}" != 1 )) ; then echo yes ; else echo no ; fi

Resposta: não

variável indefinida:

$ AA=1 ; if (( "10#0${BB}" == 1 )) ; then echo yes ; else echo no ; fi

Resposta: não

$ AA=1 ; if (( "10#0${BB}" != 1 )) ; then echo yes ; else echo no ; fi

Resposta: sim

$ AA=1 ; if (( "10#0${BB}" == 0 )) ; then echo yes ; else echo no ; fi

Resposta: sim

Isso evita erros de todos os tipos.

Você provavelmente está ciente de toda a sintaxe, mas aqui estão algumas dicas:

  • Use aspas. Evite que "blank" seja nothing .
  • A nova notação moderna para variáveis é ${variable} .
  • Adicionar um zero concatenado antes do seu número também evita "nenhum número".
  • Mas espere, adicionar um zero faz com que o número se torne base-8 . Você receberá um erro como:
    • value too great for base (error token is "08") para números acima de 7 . É quando 10# entra em jogo:
    • 10# força o número a ser base-10 .
por 19.11.2017 / 02:15
-3

Isto pode ser feito simplesmente desta forma, pois $? lhe dá o status do último comando executado.

Então pode ser

#!/bin/sh

... some command ...

if [ $? == 0 ] ; then
  echo '<the output message you want to display>'
else 
  echo '<failure message>'
fi
    
por 18.10.2015 / 20:57