Como posso fazer algo assim no bash?
if "`command` returns any error";
then
echo "Returned an error"
else
echo "Proceed..."
fi
Como posso fazer algo assim no bash?
if "`command` returns any error";
then
echo "Returned an error"
else
echo "Proceed..."
fi
Respostas:
Como fazer algo condicionalmente se um comando tiver êxito ou falha
É exatamente isso que a if
declaração do bash faz:
if command ; then
echo "Command succeeded"
else
echo "Command failed"
fi
Adicionando informações de comentários: você não precisa usar a [
... ]
sintaxe neste caso. [
é em si um comando, quase equivalente a test
. É provavelmente o comando mais comum a ser usado em um arquivo if
, o que pode levar à suposição de que ele faz 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.
Editar: citou a pergunta na parte superior para maior clareza (esta resposta não aparece na parte superior da página).
then
em uma linha separada.
if ! command ; then ... ; fi
. [
é em si um comando e não é necessário neste caso.
if [ ! command ]
não executa command
; ele trata command
como uma string e o trata como verdadeiro porque tem um comprimento diferente de zero. [
é um sinônimo para o test
comando
Para pequenas coisas que você deseja que ocorram se um comando shell funcionar, você pode usar a &&
construção:
rm -rf somedir && trace_output "Removed the directory"
Da mesma forma, para pequenas coisas que você deseja que ocorram quando um comando do 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.
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
if
idioma de Bash . Eu prefiro a resposta de Keith Thompson.
if
é fazer isso. Todas as condições de controle de fluxo no Bash são examinadas $?
nos bastidores; é isso que eles fazem. O exame explícito de seu valor deve ser desnecessário na grande maioria dos casos, e geralmente é um antipadrão para iniciantes.
if ! cmd
bem. Caso contrário, um acordo comum é usar uma else
cláusula. Você não pode ter um vazio, then
mas às vezes vê then : nothing; else
onde o :
no-op é significativo. true
iria trabalhar lá também.
Isso funcionou para mim:
command && echo "OK" || echo "NOK"
se command
for bem-sucedido, echo "OK"
é executado e, como é bem-sucedido, a execução pára por aí. Caso contrário, &&
é ignorado e echo "NOK"
é executado.
command && echo "OK" || c=$?; echo "NOK"; $(exit $c)
command && echo "OK" || (c=$?; echo "NOK"; (exit $c))
?
echo "OK"
parte em si poderia falhar, então isso é melhor:command && (echo "OK"; exit 0) || (c=$?; echo "NOK"; (exit $c))
Deve-se notar que if...then...fi
e &&
/ ||
tipo de abordagem lida com o status de saída retornado pelo comando que queremos testar (0 em caso de 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, o GNU file
ainda sai com 0 se recebeu um arquivo não existente como argumento e find
não conseguiu localizar o usuário 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
mensagens, por exemplo, aquelas que retornaram por file
comando ou analisam a saída do comando como em find
. Para esse propósito, a case
instrução pode 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
O mais propenso a erros que eu poderia ter foi:
RR=$?
Agora, não apenas para esta situação, mas para outras que você possa enfrentar, considere:
$ 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
$ 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 todos os tipos de erros.
Você provavelmente conhece toda a sintaxe, mas aqui estão algumas dicas:
"blank"
ser nothing
.${variable}
.base-8
. Você receberá um erro como:
value too great for base (error token is "08")
para números acima 7
. É quando 10#
entra em jogo:10#
força o número a ser base-10
.Você consegue fazer isso:
if ($( ping 4.4.4.4 -c1 > /dev/null )) ; then
echo "ping response succsess!!!"
fi
ping
é capturada em vista de executá-lo como um comando. Mas como a saída é redirecionada para / dev / null, essa sempre será a string vazia. Portanto, você não está executando nada em um subshell, o que significa que o status de saída anterior (do subshell de substituição de comando, que é ping) será mantido. Obviamente, a maneira correta está if ping ...; then
aqui.
Como observado em outra parte deste segmento, a pergunta original basicamente se responde. Aqui está uma ilustração mostrando que as if
condições também podem ser aninhadas.
Este exemplo usa if
para verificar se um arquivo existe e se é um arquivo regular. Se essas condições forem verdadeiras, verifique se ele tem ou não 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
#!/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
Isso pode ser feito simplesmente desta maneira, pois $?
fornece o status do último comando executado.
Então poderia ser
#!/bin/sh
... some command ...
if [ $? == 0 ] ; then
echo '<the output message you want to display>'
else
echo '<failure message>'
fi