makefile 在目标中的多行 IF 条件之前首先评估 $(eval...)
makefile evaluates $(eval...) first prior to multiline IF's condition in the target
我的问题: 内联 $(eval...) 首先计算,然后计算“IF”。我对 SSM 目标的期望是“首先评估 IF 条件,然后才评估 $(eval...)
➜ make staging ssm TARGET=i-0d334b9e3f763bfeb
if test "i-0d334b9e3f763bfeb" == "" ; then \
echo "OK"; \
\
\
echo "✔ Selected desired nodegroup staging-grafana-v1"; \
echo "✔ Selected desired instgance-id i-07cef18e93c64c795"; \
aws ssm start-session --target i-07cef18e93c64c795; \
else \
echo "✔ Selected desired instgance-id i-0d334b9e3f763bfeb"; \
aws ssm start-session --target i-0d334b9e3f763bfeb; \
fi
✔ Selected desired instgance-id i-0d334b9e3f763bfeb
Starting session with SessionId: master-admin-06c7c2b63ca2554c4
sh-4.2$
因此,我在 IF 顶部块中获得了与“fzf”相关的功能,由于 TARGET 不为空,因此应该跳过该功能。
所以本质上来说:
- 如果 TARGET 未 定义 - 一切正常。
- 如果定义了TARGET,那么我先获取两个fzf接口进行模糊搜索,然后才执行ELSE块的步骤。
.PHONY: all
.DEFAULT_GOAL := help
# ----------------------------------------------------------------------------
# Local Variables
#
# ============================================================================
help:
@grep -E '^[\.0-9a-zA-Z_-]+:.*?## .*$$' Makefile | awk 'BEGIN {FS = ":.*?## "}; {printf "⚡ 3[34m%-15s3[0m %s\n", $, $}'
staging: ## setup staging env (use: make staging plan)
@echo -n
$(eval export ENVIRONMENT=staging)
prod: ## setup prod env (use: make prod plan)
@echo -n
$(eval export ENVIRONMENT=prod)
.ONESHELL:
ssm: ## start ssm sessione
if test "$(TARGET)" == "" ; then \
echo "OK"; \
$(eval NG = $(shell aws ec2 describe-instances \
--filter Name=tag:Name,Values=$(ENVIRONMENT)* \
--query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value[] | [0]]' \
--output text \
| fzf)) \
$(eval INSTANCE_ID = $(shell aws ec2 describe-instances \
--filter Name=tag:Name,Values=${NG} \
--query 'Reservations[].Instances[].{id: InstanceId}' \
--output text \
| fzf)) \
echo "✔ Selected desired nodegroup ${NG}"; \
echo "✔ Selected desired instgance-id ${INSTANCE_ID}"; \
aws ssm start-session --target ${INSTANCE_ID}; \
else \
echo "✔ Selected desired instgance-id ${TARGET}"; \
aws ssm start-session --target ${TARGET}; \
fi
不要将 Make 语法与配方中的 shell 命令混淆。是的,Make 在将命令传递给 shell 之前扩展了 $(eval ...
函数,甚至在决定是否 运行 ssm
规则之前。
解决方法很简单;似乎没有任何理由在这里使用 eval
。变量 NG
和 INSTANCE_ID
可以是 shell 变量而不是 Make 变量。
ssm: ## start ssm sessione
if test "$(TARGET)" == "" ; then \
echo "OK"; \
NG=`aws ec2 describe-instances \
--filter Name=tag:Name,Values=$(ENVIRONMENT)* \
--query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value[] | [0]]' \
--output text \
| fzf`; \
INSTANCE_ID=`aws ec2 describe-instances \
--filter Name=tag:Name,Values=$$NG \
--query 'Reservations[].Instances[].{id: InstanceId}' \
--output text \
| fzf`; \
echo "✔ Selected desired nodegroup $$NG"; \
echo "✔ Selected desired instgance-id $$INSTANCE_ID"; \
aws ssm start-session --target $$INSTANCE_ID; \
else \
echo "✔ Selected desired instgance-id ${TARGET}"; \
aws ssm start-session --target ${TARGET}; \
fi
(P.S。如果您计划稍后在其他规则中使用这些变量,那么分配值的 if-then-else
应该在规则之外并用 Make 语法编写。)
我的问题: 内联 $(eval...) 首先计算,然后计算“IF”。我对 SSM 目标的期望是“首先评估 IF 条件,然后才评估 $(eval...)
➜ make staging ssm TARGET=i-0d334b9e3f763bfeb
if test "i-0d334b9e3f763bfeb" == "" ; then \
echo "OK"; \
\
\
echo "✔ Selected desired nodegroup staging-grafana-v1"; \
echo "✔ Selected desired instgance-id i-07cef18e93c64c795"; \
aws ssm start-session --target i-07cef18e93c64c795; \
else \
echo "✔ Selected desired instgance-id i-0d334b9e3f763bfeb"; \
aws ssm start-session --target i-0d334b9e3f763bfeb; \
fi
✔ Selected desired instgance-id i-0d334b9e3f763bfeb
Starting session with SessionId: master-admin-06c7c2b63ca2554c4
sh-4.2$
因此,我在 IF 顶部块中获得了与“fzf”相关的功能,由于 TARGET 不为空,因此应该跳过该功能。
所以本质上来说:
- 如果 TARGET 未 定义 - 一切正常。
- 如果定义了TARGET,那么我先获取两个fzf接口进行模糊搜索,然后才执行ELSE块的步骤。
.PHONY: all
.DEFAULT_GOAL := help
# ----------------------------------------------------------------------------
# Local Variables
#
# ============================================================================
help:
@grep -E '^[\.0-9a-zA-Z_-]+:.*?## .*$$' Makefile | awk 'BEGIN {FS = ":.*?## "}; {printf "⚡ 3[34m%-15s3[0m %s\n", $, $}'
staging: ## setup staging env (use: make staging plan)
@echo -n
$(eval export ENVIRONMENT=staging)
prod: ## setup prod env (use: make prod plan)
@echo -n
$(eval export ENVIRONMENT=prod)
.ONESHELL:
ssm: ## start ssm sessione
if test "$(TARGET)" == "" ; then \
echo "OK"; \
$(eval NG = $(shell aws ec2 describe-instances \
--filter Name=tag:Name,Values=$(ENVIRONMENT)* \
--query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value[] | [0]]' \
--output text \
| fzf)) \
$(eval INSTANCE_ID = $(shell aws ec2 describe-instances \
--filter Name=tag:Name,Values=${NG} \
--query 'Reservations[].Instances[].{id: InstanceId}' \
--output text \
| fzf)) \
echo "✔ Selected desired nodegroup ${NG}"; \
echo "✔ Selected desired instgance-id ${INSTANCE_ID}"; \
aws ssm start-session --target ${INSTANCE_ID}; \
else \
echo "✔ Selected desired instgance-id ${TARGET}"; \
aws ssm start-session --target ${TARGET}; \
fi
不要将 Make 语法与配方中的 shell 命令混淆。是的,Make 在将命令传递给 shell 之前扩展了 $(eval ...
函数,甚至在决定是否 运行 ssm
规则之前。
解决方法很简单;似乎没有任何理由在这里使用 eval
。变量 NG
和 INSTANCE_ID
可以是 shell 变量而不是 Make 变量。
ssm: ## start ssm sessione
if test "$(TARGET)" == "" ; then \
echo "OK"; \
NG=`aws ec2 describe-instances \
--filter Name=tag:Name,Values=$(ENVIRONMENT)* \
--query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value[] | [0]]' \
--output text \
| fzf`; \
INSTANCE_ID=`aws ec2 describe-instances \
--filter Name=tag:Name,Values=$$NG \
--query 'Reservations[].Instances[].{id: InstanceId}' \
--output text \
| fzf`; \
echo "✔ Selected desired nodegroup $$NG"; \
echo "✔ Selected desired instgance-id $$INSTANCE_ID"; \
aws ssm start-session --target $$INSTANCE_ID; \
else \
echo "✔ Selected desired instgance-id ${TARGET}"; \
aws ssm start-session --target ${TARGET}; \
fi
(P.S。如果您计划稍后在其他规则中使用这些变量,那么分配值的 if-then-else
应该在规则之外并用 Make 语法编写。)