2014-04-15 25 views
10

Dire che ho i seguenti file:equivalente a pipefail in GNU make?

buggy_program:

#!/bin/sh 
echo "wops, some bug made me exit with failure" 
exit 1 

Makefile:

file.gz: 
    buggy_program | gzip -9 -c >[email protected] 

Ora, se digito make, GNU make sarà lieto di costruire file.gz anche se buggy_program terminato con non- stato zero.

In bash potrei fare set -o pipefail per uscire da una pipeline con errore se almeno un programma nella pipeline termina con un errore. Esiste un metodo simile in GNU make? O qualche soluzione alternativa che non riguardi i file temporanei? (La ragione di gzipping qui è proprio per evitare un file temporaneo enorme.)

risposta

2

Ecco una possibile soluzione che non richiede bash. Immagina di avere due programmi thisworks e thisfails che falliscono o funzionano bene, rispettivamente. Quindi il seguente ti lascerà solo con work.gz, eliminando fail.gz, ad es. creare il target make gzipped se e solo se il programma eseguito correttamente:

all: fail.gz work.gz 

work.gz: 
    (thisworks && touch [email protected]) | gzip -c -9 >[email protected] 
    rm [email protected] || rm [email protected] 

fail.gz: 
    (thisfails && touch [email protected]) | gzip -c -9 >[email protected] 
    rm [email protected] || rm [email protected] 

Spiegazione:

Nella prima riga della regola work.gz, thisworks uscirà con successo, e un file verrà creato work.gz.ok, e tutto lo stdout passa attraverso gzip in work.gz. Poi nella seconda riga, perché work.gz.ok esiste, il primo comando rm esce anche con successo - e dal momento che è ||short-circuiting, il secondo rmnon viene eseguito e così work.gz non viene eliminato.

OTOH, nella prima riga della regola fail.gz, thisfails uscirà con il fallimento, e fail.gz.ok sarà non essere creato. Tutto lo stdout passa ancora attraverso gzip in fail.gz. Poi nella seconda riga, perché fail.gz.ok fa non esistono, i primi rm comando termina con insufficienza, in modo || cerca il secondo comando rm che cancella il file fail.gz.


Per controllare facilmente che questo funziona come dovrebbe, è sufficiente sostituire thisworks e thisfails con i comandi true e false, rispettivamente, metterlo in un Makefile e digitare make.

(Grazie alle persone gentili di #autotools per avermi aiutato con questo.)

+0

Può spiegare questa risposta un po '? Non sono sicuro di capire bene cosa sta succedendo qui. – wheeler

+0

certo, ho modificato la domanda - è stato d'aiuto? – unhammer

2

si potrebbe fare:

SHELL=/bin/bash 

.DELETE_ON_ERROR: 
file.gz: 
    set -o pipefail; buggy_program | gzip -9 -c >[email protected] 

ma questo funzionare solo con bash.

Problemi correlati