ASH: verifique o código de saída do comando dentro da instrução if

0

Estou tentando retornar um código de saída 0 se um comando sair com o código 143 (tempo limite, do "comando timeout"), 1 caso contrário. Devido à restrição externa (script CI), eu tenho que iniciar o comando e fazer a verificação na cláusula if.

Aqui está o que eu uso atualmente:

if timeout -t 10 *command* || [ $? = 143 ]
then exit 0
else exit 1
fi

ATM, sempre sai com um código 0.

    
por Dremor 07.04.2018 / 13:55

2 respostas

3

Seu script não está fazendo o que você deseja porque, quando timeout -t 10 command tem um status de saída igual a 0 - que é o status de saída considerado verdadeiro no shell script - o comando timeout -t 10 command || [ $? = 143 ] é concluído com uma saída status 0 e não faz com que o lado direito de || seja executado. Da mesma forma, se você substituiu || por && , qualquer status de saída diferente de zero do lado esquerdo seria o status de saída de todo o comando e o lado direito não seria executado .

Você deve executá-los como dois comandos separados , separando-os com ; ou newline. Se necessário, você ainda pode usá-los como a condição if quando fizer isso (veja abaixo).

Estou assumindo que é o status de saída de timeout -t 10 command , e não command (se diferente), que você precisa. Caso contrário, não está claro para mim o que você quer; como o ilkkachu , não estou familiarizado com um comando timeout que aceita uma opção -t . Normalmente eu sugiro que você faça desta forma, exceto que sua "restrição externa" pode proibi-lo, já que ele não usa if :

timeout -t 10 command
test "$?" -eq 143
exit

O comando test / [ retorna um código de saída 0 para indicar true e 1 para indicar false, e é por isso que você não precisa gravar ramificações separadas com exit 0 e exit 1 . O exit builtin, quando executado sem argumentos, faz com que o shell retorne o status de saída do último comando executado.

Se você já estiver no final do script, poderá omitir exit , porque quando o controle flui do final de um script, ele tem o mesmo efeito que exit :

timeout -t 10 command
test "$?" -eq 143

(Em ambos os casos, você pode escrever [ "$?" -eq 143 ] em vez de test "$?" -eq 143 , se desejar. Veja abaixo os detalhes sobre [ / test usage.)

Embora sua descrição tenha feito parecer que você não pode usar esse código exatamente, você deve, no entanto, modificá-lo para assumir o formulário necessário. Você disse que não deve apenas fazer o teste, mas também iniciar o comando na cláusula if . Isso parece proibir a abordagem legível e idiomática sugerida por Hauke Laging de executar o comando antes do if .

Se você não puder fazer isso, inclua o comando na condição if como estava, mas separe-o do comando test / [ com ; em vez de um || :

if timeout -t 10 command; [ "$?" -eq 143 ]; then
    exit 0
else
    exit 1
fi

(Você pode usar omitindo " " em torno de $? . Você também pode escrever = em vez de 143 , embora seja confuso porque = significa texto em vez de numérico Você pode escrever test "$?" -eq 143 em vez de [ "$?" -eq 143 ] se desejar.

A razão pela qual isso funciona é que você tem permissão para escrever uma condição if que consiste em vários comandos separados por ponto-e-vírgula ou até mesmo novas linhas. É por isso que a gramática de shell requer que você escreva then para indicar o final da condição if . Portanto, você não precisa usar o uso circunscrito do operador && ou || quando sua meta é executar dois comandos como uma condição if , ao mesmo tempo em que faz com que if teste apenas o segundo.

Note que estou apenas sugerindo isso porque você disse que tinha que estar na condição if . Eu não recomendo scripts assim quando você não precisa.

    
por 07.04.2018 / 15:08
2
timeout -t 10 command
if [ $? -eq 143 ]; then
    exit 0
else
    exit 1
fi
    
por 07.04.2018 / 14:18