2012-12-08 10 views
23

Mam plik Makefile w celu odtworzenia mojej bazy danych, w tym w razie potrzeby jej zniszczenia. To nie działa.Jak używać zmiennych powłoki w akcjach 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 

Running to powoduje błąd:

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

Dlaczego to jest złe? Wygląda na prawidłowy Bash, o ile mogę powiedzieć? Czy są specjalne względy, które muszę zrobić, robiąc to w Makefile?

UPDATE:

Korzystanie odpowiedź przyjechałem w wersji roboczej:

.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 

Odpowiedz

38

Istnieją co najmniej dwa czynniki. $() odnosi się do zmiennej Make. Musisz wymigać się od $, aby dokonać podstawienia komend. Ponadto polecenia powłoki muszą znajdować się w jednym wierszu. Spróbuj:

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 

Z drugiej strony, wydaje się, że byłoby prościej po prostu zawsze starają się usunąć bazę danych i pozwolić awaria:

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

Istnieje jeszcze kilka niuansów o „wszystko na jedna linia ", o której warto dyskutować: (tradycyjnie i przenośnie) wszystko, co chcesz wykonać za pomocą ** tej samej powłoki **, musi być w jednej linii logicznej _make_. Więc 'exists = ...' i 'if ... fi' musi być wykonane w pojedynczym wierszu poleceń ze średnikami i odwróconymi ukośnikami, ale' createdb ... 'może z radością pozostać jako oddzielne drugie polecenie w recepturze. –

+1

Dla czytelnika: Upewnij się, że umieściłeś '\' na końcu twojego 'VAR =" foo "\' statement – redolent

+1

"Wszystko w jednym wierszu" można rozluźnić, używając '.ONESHELL:' jak opisano w https: //www.gnu.org/software/make/manual/html_node/One-Shell.html#One- Shell – sdive

Powiązane problemy