2012-12-08 2 views
23

Ho il seguente in un Makefile allo scopo di ricreare il mio database incluso distruggerlo se necessario. Non funziona.Come utilizzare le variabili di shell nelle azioni Makefile?

.PHONY: rebuilddb 
    exists=$(psql postgres --tuples-only --no-align --command "SELECT 1 FROM pg_database WHERE datname='the_db'") 
    if [ $(exists) -eq 1 ]; then 
     dropdb the_db 
    fi 
    createdb -E UTF8 the_db 

esecuzione si traduce in un errore:

$ make rebuilddb 
exists= 
if [ -eq 1 ]; then 
/bin/sh: -c: line 1: syntax error: unexpected end of file 
make: *** [rebuilddb_postgres] Error 2 

Perché questo è sbagliato? Per quanto ne so, sembra Bash valido? Ci sono delle considerazioni particolari che devo fare quando faccio questo in un Makefile?

UPDATE:

Utilizzando la risposta sono arrivato a una versione funzionante:

.PHONY: rebuilddb 
    exists=$$(psql postgres --tuples-only --no-align --command "SELECT 1 FROM pg_database WHERE datname='the_db'"); \ 
    if [ "$$exists" == "1" ]; then \ 
     dropdb the_db; \ 
    fi; 
    createdb -E UTF8 the_db 

risposta

38

Ci sono almeno due considerazioni. $() fa riferimento a Crea variabile. È necessario sfuggire allo $ per eseguire la sostituzione di comando. Inoltre, i comandi della shell devono essere tutti su una riga. Prova:

exists=$$(psql postgres --tuples-only --no-align --command "SELECT 1 FROM \ 
    pg_database WHERE datname='the_db'"); \ 
    if [ "$$exists" -eq 1 ]; then \ 
     dropdb the_db; \ 
    fi; \ 
    createdb -E UTF8 the_db 

D'altra parte, sembra che sarebbe più semplice per provare solo sempre di eliminare il database, e consentire il fallimento:

rebuilddb: 
    -dropdb the_db # Leading - instructs make to not abort on error 
    createdb -E UTF8 the_db 
+3

Ci sono un paio di sfumature su "tutti su una riga "che vale la pena di discutere: (tradizionalmente e portabilmente) tutto ciò che si vuole essere eseguito dalla ** stessa shell ** deve essere su una riga logica _make_. Quindi 'exists = ...' e 'if ... fi' deve essere trasformato in una singola riga di comando con punto e virgola e barre rovesciate, ma' createdb ... 'potrebbe rimanere felicemente come un secondo comando separato nella ricetta. –

+1

Al lettore: Assicurati di mettere il '\' alla fine della tua istruzione 'VAR =" pippo "\" – redolent

+1

Il "tutto in una riga" può essere rilassato usando '.ONESHELL:' come descritto in https: //www.gnu.org/software/make/manual/html_node/One-Shell.html#One-Shell – sdive