Sostituzione del processo in GNU Makefile


11

A un prompt di bash, è possibile eseguire diff usando pseudo file:

diff <(echo test) <(echo test)

Aggiungere questo come è in un Makefile non riesce:

all:
        diff <(echo test) <(echo test)

L'errore (suggerimento: / bin / sh punta a / bin / bash su questo sistema):

/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `diff <(echo test) <(echo test)'

Che cosa significa, e c'è un modo per diff ancora due output senza usare file temporanei?

Risposte:


20

/bin/shpotrebbe essere bashsul tuo sistema, ma quando viene invocato come sh, bashsarà in esecuzione in modalità POSIX (come se POSIXLY_CORRECTfosse stato definito, o fosse iniziato con --posix).

In questa modalità, non esistono sostituzioni di processo.

soluzioni:

all:
    command1 >file1
    command2 >file2
    diff file1 file2
    rm -f file1 file2

Alternativa:

all:
    bash -c "diff <(command1) <(command2)"

O semplicemente definire la variabile Makefile SHELLcome /bin/bash:

SHELL=/bin/bash

Se vuoi la portabilità, scegli la prima soluzione. Se stai bene con una dipendenza bash, scegli il secondo. Se inoltre non è necessario preoccuparsi delle makeimplementazioni non GNU , utilizzare la terza.


Per quanto riguarda l'impostazione SHELL: lo standard POSIX afferma che gli eseguibili nei Makefile dovrebbero essere invocati con la system()funzione libreria C da make. Non è garantito che questa funzione utilizzi la SHELLvariabile d'ambiente (infatti, lo standard è scoraggiato). Lo standard va anche oltre per dire che l'impostazione della variabile Makefile SHELLnon dovrebbe influenzare la variabile d'ambiente SHELL . Nella maggior parte delle implementazioni makeche conosco, tuttavia, la variabile Makefile SHELLverrà utilizzata per eseguire i comandi.

Il suggerimento nel Razionale per l' makeutilità è di usare bash -c:

La MAKESHELLfunzionalità storica e le funzionalità correlate fornite da altre makeimplementazioni sono state omesse. In alcune implementazioni viene utilizzato per consentire a un utente di ignorare la shell da utilizzare per eseguire i makecomandi. Questo era confuso; per un portatile make, la shell dovrebbe essere scelta dallo scrittore di makefile. Inoltre, uno scrittore di makefile non può richiedere l'uso di una shell alternativa e deve comunque considerare il makefile portatile. Mentre sarebbe possibile standardizzare un meccanismo per specificare una shell alternativa, le implementazioni esistenti non concordano su tale meccanismo e gli autori di makefile possono già invocare una shell alternativa specificando il nome della shell nella regola per una destinazione; per esempio:

python -c "foo"


C'è un modo per invocare bashnel Makefile o qualsiasi altra soluzione al problema diff senza usare file temporanei?
Johannes,

Basta usare due file temporanei, questo è più o meno ciò che il metodo di sostituzione del processo farebbe comunque sotto il cofano.
Kusalananda

3
Puoi anche impostare SHELLsu /bin/bashnel Makefile.
Stephen Kitt,

1
@Johannes Kusalananda ha aggiunto le informazioni alla sua risposta, il che è fantastico poiché presenta una serie di opzioni e le circostanze in cui possono essere utilizzate. Preferirei che accettassi questa risposta ... (Ma apprezzo il sentimento!)
Stephen Kitt,

2
Le informazioni secondo cui l'utilizzo della variabile SHELL non è conforme a POSIX sono state molto utili. Forse è ancora meglio usare bash -c.
Johannes,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.