it-swarm.dev

Wie verwende ich Shell-Variablen in Makefile-Aktionen?

Ich habe folgendes in einem Makefile, um meine Datenbank neu zu erstellen und sie gegebenenfalls zu zerstören. Es funktioniert nicht.

.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

Das Ausführen führt zu einem Fehler:

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

Warum ist das falsch? Soweit ich das beurteilen kann, sieht es nach gültigem Bash aus? Gibt es spezielle Überlegungen, die ich in einem Makefile beachten muss?

UPDATE:

Mit der Antwort bin ich zu einer funktionierenden Version gekommen:

.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
27
hekevintran

Es gibt mindestens zwei Überlegungen. $() verweist auf eine Make-Variable. Sie müssen den Code $ für die Befehlsersetzung deaktivieren. Außerdem müssen sich die Shell-Befehle in einer Zeile befinden. Versuchen:

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

Auf der anderen Seite scheint es einfacher zu sein, die Datenbank einfach immer zu löschen und Fehler zuzulassen:

rebuilddb:
    -dropdb the_db  # Leading - instructs make to not abort on error
    createdb -E UTF8 the_db
43
William Pursell

Zur Vervollständigung der Verwendung in $ (eval $ (call ...)

Die Verwendung in dynamischen Generierungsregeln müssen Sie den Shell-Variablen mit $$$$ entziehen.

Hier ist ein Beispiel, das mit "GNU Make 4.2.1" getestet wurde:

MY_LIBS = a b c

a_objs = a1.o a2.o
b_objs = b1.o b2.o b3.o
c_objs = c1.o c2.o c3.o c4.o

standard: Libs

# function lib_rule (name, objs)

definiere lib_rule
lib $ (1) .a: $ (2)
exit 1 | tee make.log; test $$$$ {PIPESTATUS [0]} -eq 0
Endef

# Regeln generieren
$ (foreach L, $ (MY_LIBS), $ (eval $ (Aufruf lib_rule, $ (L), $ ($ (L) _objs))))

# Aufruf generierte Regeln
libs: $ (patsubst%, lib% .a, $ (MY_LIBS))

# Dummy-Objektgenerierung
% .o:% c
touch $ @

# Scheinquellengenerierung
% .c:
touch $ @

sauber::
rm -f * .c * .o lib * .a make.log

Die Ausgabe: 'make -Rr'

ausfahrt 1 | tee make.log; test $ {PIPESTATUS [0]} -eq 0
make: *** [Makefile: 18: liba.a] Fehler 1

Ergebnis des letzten Befehls in Pipe ist true from tee . Sie können die bash-Variable PIPESTATUS [0] mit dem Wert false from exit 1

Schauen Sie sich die Datenbank an: 'make -Rrp'

definiere lib_rule
lib $ (1) .a: $ (2)
exit 1 | tee make.log; test $$$$ {PIPESTATUS [0]} -eq 0
Endef

...

libc.a: c1.o c2.o c3.o c4.o
exit 1 | tee make.log; test $$ {PIPESTATUS [0]} -eq 0

0
Clemens1509