仅在shell命令输出为空时在Makefile中执行命令

时间:2019-10-13 21:42:52

标签: makefile

仅在shell命令输出为空时,我才尝试运行一些命令,如下所示:

setup-database:
    database=$(shell docker-compose exec mariadb mysql -e "select schema_name from information_schema.schemata where schema_name = 'dbname'" --silent --silent)

ifeq ($(strip $(database)),)
    docker-compose exec mariadb mysql -e "create database dbname"

    # ...
endif

但是它不起作用。不管第一个命令的输出是什么,它都会在if内部执行命令。

2 个答案:

答案 0 :(得分:1)

问题在于您混用了Make命令和shell命令。

setup-database:
    database=$(shell docker-compose some things)
ifeq ($(strip $(database)),)
    docker-compose some other things
    # ...
endif

ifeq ... endif Make 条件。 Make将在运行任何规则之前对其进行评估;变量database首先是空的,因此Make总是在配方中包含该规则块。 (实际上, make 变量database保持为空。被分配了值的database shell 变量。

由于要在执行规则时测试变量,因此它应该是一个shell变量,并使用shell条件测试。在命令行上,这将是:

database=`docker-compose some things`
if [ -z $database ]
  then
  docker-compose some other things
  ...
fi

(我不认为[ -z STRING ]关心空格,所以我们不需要$(strip ...)。)

由于配方中的每个命令都在单独的子外壳中运行,因此整个过程必须在一行上,否则变量的值将丢失:

database=`docker-compose some things`; if [ -z $database ] ; then docker-compose some other things; ...; fi

当我们将其放入makefile中时,我们使用$(shell ...)而不是反引号,并转义$(并可选地使用一些反斜杠使规则更具可读性):

setup-database:
    database=$(shell docker-compose some things);\
  if [ -z $$database ] ; then \
  docker-compose some other things; \
  ... \
  fi

答案 1 :(得分:0)

Make不提供将特定操作的值提取到变量中的直接选项。 要考虑的两个选项:-使用制造符号,跟踪文件结果。

  1. 创建商标符号
  # Note: nothing get executed.
db_check=$(shell docker-compose exec mariadb mysql -e "select schema_name from information_schema.schemata where schema_name = 'dbname'" --silent --silent)

In setup-database:
    # Create shell variable. Useful only on the same line.
    database="${db_check}" ; [ "$database" ] || docker-compose exec mariadb mysql -e "create database dbname"

    # ...