仅在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
内部执行命令。
答案 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不提供将特定操作的值提取到变量中的直接选项。 要考虑的两个选项:-使用制造符号,跟踪文件结果。
# 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"
# ...