Não pare de fazer se um comando falhar, mas verifique o status de saída

16

Estou tentando instruir o GNU Make 3.81 para não parar se um comando falhar (então prefixo o comando com - ), mas também quero verificar o status de saída no próximo comando e imprimir uma mensagem mais informativa. No entanto, meu Makefile abaixo falha:

$ cat Makefile 
all:
    -/bin/false
    ([ $$? -eq 0 ] && echo "success!") || echo "failure!"
$
$ make
/bin/false
make: [all] Error 1 (ignored)
([ $? -eq 0 ] && echo "success!") || echo "failure!"
success!

Por que o Makefile acima ecoa "sucesso!" em vez de "fracasso!" ?

update:

Seguindo e expandindo a resposta aceita, abaixo está como deve ser escrito:

failure:                                                                                                                                                                                                                                      
    @-/bin/false && ([ $$? -eq 0 ] && echo "success!") || echo "failure!"                                                                                                                                                                 
success:                                                                                                                                                                                                                                      
    @-/bin/true && ([ $$? -eq 0 ] && echo "success!") || echo "failure!"     
    
por Marcus Junius Brutus 04.09.2014 / 17:13

3 respostas

12

Cada comando update em uma regra Makefile é executado em um shell separado. Então $? não contém o status de saída do comando com falha anterior, ele contém o valor padrão para $? em um novo shell. É por isso que o seu [$? -eq 0] teste sempre é bem sucedido.

    
por 04.09.2014 / 20:16
6

Você não precisa do teste de $? , pois && funciona se $? for zero e || for processado no caso de um valor de retorno diferente de zero.

E você não precisa de menos, já que o valor de retorno a ser feito é retirado da última chamada de programa da linha. Então isso funciona bem

falha:

      @/bin/false && echo "success!" || echo "failure!" 

sucesso:

      @/bin/true && echo "success!" || echo "failure!"

O oposto acontece: Se você quer fazer sua própria mensagem e quer quebrar o processo de make de qualquer forma com um valor diferente de zero, você precisa escrever algo assim:

falha:

      @/bin/false && echo "success!" || { echo "failure!"; exit 1; }
    
por 10.02.2015 / 15:24
5

De o GNU faz a documentação :

When errors are to be ignored, because of either a ‘-’ or the ‘-i’ flag, make treats an error return just like success, except that it prints out a message that tells you the status code the shell exited with, and says that the error has been ignored.

Para utilizar o status de saída de make em um caso como este, execute make de um script:

#!/bin/bash
make
([ $? -eq 0 ] && echo "success!") || echo "failure!"

E seu Makefile deve conter:

all:
    /bin/false
    
por 04.09.2014 / 20:04

Tags