2012-10-25 13 views
9

Vorrei verificare il risultato di una ricerca di grep in un Makefile. Contrariamente a this solution, non desidero utilizzare il comando shell. Inoltre, non voglio che il Makefile generi un errore quando grep non trova la stringa (il codice di uscita di 1 viene trattato come un errore).Grep exit codes in Makefile

i seguenti cerca di ignorare l'errore e controllare il codice di uscita:

all: 
    -grep term log* 
    echo $$? 
    @case "$$?" in \ 
     0)\ 
    echo "found";; \ 
    *) \ 
    echo "not found";;\ 
    esac; 

Purtroppo, il codice di uscita è sempre 0.

+0

Oh, stavo cercando questo! Ha reso la mia giornata. Grazie – lzap

risposta

7

Le linee separate di una serie di azioni in un makefile sono normalmente eseguito in sotto-shell separate. Per codificare ciò che stai cercando, quindi:

all: 
    if grep term log*; \ 
    then echo found; \ 
    else echo not found; \ 
    fi 

Questo è un comando singolo; verifica direttamente lo stato di uscita di grep. Nota l'uso liberale del punto e virgola; è necessario perché tutto viene appiattito quando viene passato alla shell. Nota anche che lo - non è necessario; l'istruzione nel suo complesso si chiude con lo stato 0 poiché uno dei comandi echo viene eseguito, ha esito positivo, e quello è lo stato restituito dalla sub-shell. Ma c'è un'altra parte del trucco; IIRC, lo script viene invocato con /bin/sh -e in modo che lo script venga chiuso al primo errore (diverso da zero) da un comando shell, tranne che in condizionali espliciti come if.

Se si desidera catturare in modo esplicito lo stato di grep (se non altro per essere sicuri che è stato fatto a destra), quindi:

all: 
    -grep term log*; \ 
    status=$$?; echo $$status; \ 
    if [ $$status = 0 ]; \ 
    then echo found; \ 
    else echo not found; \ 
    fi 

probabilmente è necessario il - questa volta perché il grep non viene eseguita come parte di uno shell condizionale e uno stato di uscita diverso da zero potrebbero attivare l'elaborazione -e. Non consiglio di perdere tempo con questo.

È possibile notare che è possibile eseguire i comandi cd in un'azione e poiché ciascuna azione viene eseguita separatamente, è necessario farlo ripetutamente.

install: ${PROG} 
    cd ${INSTBIN}; ${RM_F} ${PROG} 
    ${CP} ${PROG} ${INSTBIN} 
    cd ${INSTBIN}; ${CHOWN} ${OWNER}:${GROUP} ${PROG}; ${CHMOD} ${PERMS} ${PROG} 

Sì, è possibile farlo in modo diverso - Sto dimostrando un punto, non sostenendo uno stile di installare programmi.

+0

La prima soluzione è molto elegante. Con la spiegazione dettagliata, accettata! Non capisco il punto nell'ultimo paragrafo, però. –

+0

Invece di fare 'cd $ {INSTBIN}; $ {RM_F} $ {PROG} ', potrei scrivere:' $ {RM_F} $ {INSTBIN}/$ {PROG} 'senza un' cd'. Questo è tutto ciò che sto dicendo. (Lavoro su makefile in cui questo è fondamentalmente il modo in cui il codice viene copiato da un'area di compilazione - da root, a mio disgusto - alla directory di distribuzione. Non ti annoierò per come è andata così e perché non ho risolto ancora.) –

+0

Nella mia limitata esperienza di Makefile, l'unico uso di cd è chiamare un sotto-Makefile. –