Questão Como verificar se um comando foi bem sucedido?


Existe alguma maneira de verificar se há um erro na execução de um comando?

Exemplo:

test1=`sed -i "/:@/c connection.url=jdbc:oracle:thin:@$ip:1521:$dataBase" $search`
valid $test1

function valid () {
  if $test -eq 1; then
    echo "OK"
    else echo "ERROR" 
  fi
}

Eu já tentei fazer isso, mas parece que não está funcionando. Eu não sei como fazer isso.


162
2018-03-07 11:40


origem


Preferir $ (foo) sobre backticks `foo`, porque você pode aninhar, e é mais fácil distinguir de apóstrofos. - user unknown
BTW, você precisa definir uma função (validantes de você ligar. - wjandrea


Respostas:


O valor de retorno é armazenado em $?. 0 indica sucesso, outros indica erro.

some_command
if [ $? -eq 0 ]; then
    echo OK
else
    echo FAIL
fi

Como qualquer outro valor textual, você pode armazená-lo em uma variável para comparação futura:

some_command
retval=$?
do_something $retval
if [ $retval -ne 0 ]; then
    echo "Return code was not zero but $retval"
fi

Para possíveis operadores de comparação, consulte man test.


240
2018-03-07 12:06



Isso é legal ... posso segurar o erro de saída ?? !! , porque neste caso eu tenho 2 erro: erro de comando "texto" ex, arquivo não encontrado e meu erro "texto" que é, neste caso, falhou por exemplo - moata_u
@moata_u: você pode armazenar o valor em uma variável como mostrado na minha resposta. - Lekensteyn
@moata_u: Você precisa colocar um ; antes de o else e fi: `se ...; então ...; outro ...; fi - Lekensteyn
Isto é um uso inútil de test. - David Foerster
@Blauhirn [ $? ] (ou equivalente, test $?) não funciona porque $? avalia para um número (0, 1, etc.) que não é nulo. Veja o docs para test: "Se a EXPRESSÃO for omitida, 'teste' retornará falso. Se EXPRESSÃO for um único argumento, 'teste' retornará falso se o argumento for nulo e verdadeiro de outra forma." - Lekensteyn


Se você só precisa saber se o comando foi bem-sucedido ou não, não se incomode em testar $?, apenas teste o comando diretamente. Por exemplo.:

if some_command; then
    printf 'some_command succeeded\n'
else
    printf 'some_command failed\n'
fi

E atribuir a saída a uma variável não altera o valor de retorno (bem, a menos que ela se comporte de forma diferente quando a saída padrão não for um terminal, é claro).

if output=$(some_command); then
    printf 'some_command succeded, the output was «%s»\n' "$output"
fi

http://mywiki.wooledge.org/BashGuide/TestsAndConditionals explica if em mais detalhes.


60
2018-03-08 23:54



E se você quiser fazer algo diferente de ramificar como armazenar o booleano de ter falhado ou não em um .ini? Então sua variável de saída não faz isso, mas $? faz, então você está incorreto em dizer que testar o comando diretamente é estritamente melhor. - Timothy Swan


command && echo OK || echo Failed

19
2017-12-01 21:19



E se command retorna erro na tela, como escondê-lo? - Sigur
E se command escreve erros para stderr, você pode usar o formulário command 2> /dev/null && echo OK || echo Failed. o 2> /dev/null redireciona a saída do stderr para /dev/null. No entanto, alguns utilitários gravam erros no stdout (mesmo que isso seja uma prática ruim). Nesse caso, você pode omitir o 2 do redirecionamento, mas perderá qualquer saída do comando. Este método de verificação do sucesso é bom para a lógica ternária simples, mas para um comportamento mais complexo, é melhor verificar $? para o sucesso do comando ou use o if método de bloco delineado na resposta do @ geirha. - Bender the Greatest


$? deve conter o status de saída do comando anterior, que deve ser zero para nenhum erro.

Então, algo como;

cd /nonexistant
if [ $? -ne 0 ]
then
    echo failed
else
    echo success!
fi

na maioria dos casos, é mais fácil usar os comandos && construct para cadeia que precisam depender um do outro. assim cd /nonexistant && echo success! seria não eco sucesso porque o comando quebra antes &&. O corolário disso é ||, onde cd /nonexistant || echo fail  seria eco falhar porque o cd falhou. (isso se torna útil se você usar algo como || exit, que terminará o script se o comando anterior falhar).


12
2018-03-07 12:04



Isso é legal ... posso segurar o erro de saída ?? !! , porque neste caso eu tenho 2 erro: erro de comando "texto" ex, arquivo não encontrado e meu erro "texto" que é, neste caso, falhou por exemplo - moata_u
@moata_u, ver mywiki.wooledge.org/BashFAQ/002 - geirha


command && echo $? || echo $?

4
2017-08-12 16:01





Para prova de erro seus comandos:

execute [INVOKING-FUNCTION] [COMMAND]

execute () {
    error=$($2 2>&1 >/dev/null)

    if [ $? -ne 0 ]; then
        echo "$1: $error"
        exit 1
    fi
}

Inspirado na manufatura enxuta:


2
2017-12-29 04:20





Deve-se notar que if...then...fi e &&/|| o tipo de abordagem 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 o habitual if e &&/|| abordagens não funcionam 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 foi possível 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 mensagens, por ex. aqueles que retornaram file comando, ou analisar a saída do comando como em find. Para esse efeito, case declaraçã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

(Esta é uma repostagem da minha própria resposta sobre questão relacionada em unix.stackexchange.com )


0
2017-11-13 18:58





Como mencionado em muitas outras respostas, um teste simples de $? vai fazer assim

if [ $? -eq 0 ]; then something; fi

Se você quiser testar se o comando falhou, você pode usar uma versão mais curta bash (mas talvez exagero) da seguinte forma:

if (($?)); then something; fi

Isso funciona usando o (( )) modo aritmético, então se o comando retornou success, isto é $? = 0 então o teste avalia para ((0)) quais testes como falsecaso contrário ele retornará true.

Para testar sucesso, você poderia usar:

if ! (($?)); then something; fi

mas já não é muito mais curto que o primeiro exemplo.


0
2017-08-16 21:07