我在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
运行它会导致错误:
$ make rebuilddb
exists=
if [ -eq 1 ]; then
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [rebuilddb_postgres] Error 2
为什么这是错的?据我所知,它看起来像有效的Bash?在Makefile中执行此操作时是否需要特别注意?
更新
使用答案我到达了一个工作版本:
.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
答案 0 :(得分:44)
至少有两个考虑因素。 $()
引用Make变量。您必须转义$
来执行命令替换。此外,shell命令必须全部在一行上。尝试:
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
另一方面,似乎总是试图删除数据库并允许失败更简单:
rebuilddb:
-dropdb the_db # Leading - instructs make to not abort on error
createdb -E UTF8 the_db
答案 1 :(得分:0)
在动态生成规则中的用法,必须使用$$转义shell变量。
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默认值:库
#函数lib_rule(name,objs)
定义lib_rule
lib $(1).a:$(2)
出口1 |发球make.log;测试 $$$$ {PIPESTATUS [0]} -eq 0
尾巴#生成规则
$(foreach L,$(MY_LIBS),$(eval $(call lib_rule,$(L),$($(L)_objs))))#调用生成的规则
库:$(patsubst%,lib%.a,$(MY_LIBS))#虚拟对象生成
%.o:%。c
触摸$ @
#虚拟源生成
%.c:
触摸$ @
clean ::
rm -f * .c * .o lib * .a make.log
输出:'make -Rr'
出口1 |发球make.log;测试 $ {PIPESTATUS [0]} -eq 0
make:*** [Makefile:18:liba.a]错误1
管道中的最后一条命令的结果为 tee 中的 true 。您可以看到bash变量 PIPESTATUS [0] 从退出1
的值为 false观看数据库:“ make -Rrp”
定义lib_rule
lib $(1).a:$(2)
出口1 |发球make.log;测试 $$$$ {PIPESTATUS [0]} -eq 0
尾巴
...
libc.a:c1.o c2.o c3.o c4.o
出口1 |发球make.log;测试 $$ {PIPESTATUS [0]} -eq 0