Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use shell variables in Makefile actions?

Tags:

bash

makefile

I have the following in a Makefile for the purpose of recreating my database including destroying it if necessary. It does not work.

.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 it results in an error:

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

Why is this wrong? It looks like valid Bash as far as I can tell? Are there special considerations I must make when doing this in a Makefile?

UPDATE:

Using the answer I arrived at a working version:

.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 
like image 292
hekevintran Avatar asked Dec 08 '12 05:12

hekevintran


People also ask

Can you use bash commands in a makefile?

So put SHELL := /bin/bash at the top of your makefile, and you should be good to go. See "Target-specific Variable Values" in the documentation for more details. That line can go anywhere in the Makefile, it doesn't have to be immediately before the target.

What shell is used in makefile?

$(shell) $(shell) is a special function in gmake that runs an external command and captures the output for use in the makefile.


1 Answers

There are at least two considerations. $() references a Make variable. You must escape the $ to do command substitution. Also, the shell commands must be all on one line. Try:

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 

On the other hand, it seems like it would be simpler to just always try to drop the database, and allow failure:

rebuilddb:     -dropdb the_db  # Leading - instructs make to not abort on error     createdb -E UTF8 the_db 
like image 139
William Pursell Avatar answered Sep 22 '22 15:09

William Pursell