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

仅当shell命令输出为空时才在Makefile中执行命令,makefile,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-com

我尝试仅在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
中的命令,而不考虑第一个命令的输出。

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

  • 创建制造符号

  • 问题是您混合了Make命令和shell命令

    setup-database:
        database=$(shell docker-compose some things)
    ifeq ($(strip $(database)),)
        docker-compose some other things
        # ...
    endif
    
    如果。。。endif是一个Make条件。Make将在运行任何规则之前对其进行评估;变量
    数据库
    一开始是空的,因此Make总是在配方中包含该规则块。(事实上,make变量
    数据库
    仍然是空的。获得赋值的
    数据库
    是一个shell变量

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

    database=`docker-compose some things`
    if [ -z $database ]
      then
      docker-compose some other things
      ...
    fi
    
    (我不认为
    [-z STRING]
    关心空格,所以我们不需要
    $(strip…

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

    database=`docker-compose some things`; if [ -z $database ] ; then docker-compose some other things; ...; fi
    
    当我们将其放入makefile中时,我们使用
    $(shell…
    而不是反勾号,并转义
    $
    (还可以选择使用一些反斜杠使规则更具可读性):


    因此,如果,就没有办法在
    中执行多行代码了?返回状态如何?可以将其提取到变量中吗?@IulianOnofrei:返回状态可以提取,但这不是你的问题。你想如何使用它?简单地说,如果没有创建数据库,创建它,然后执行其他命令。
    
    database=`docker-compose some things`; if [ -z $database ] ; then docker-compose some other things; ...; fi
    
    setup-database:
        database=$(shell docker-compose some things);\
      if [ -z $$database ] ; then \
      docker-compose some other things; \
      ... \
      fi