如何在Makefile操作中使用shell变量?

时间:2012-12-08 05:22:48

标签: bash makefile

我在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

2 个答案:

答案 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)

为了完整起见,在$(eval $(call ...)

中的用法

在动态生成规则中的用法,必须使用$$转义shell变量。

以下是已通过“ GNU Make 4.2.1”测试的示例:

  

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