【问题标题】:Running a command from a variable in make从make中的变量运行命令
【发布时间】:2025-11-28 20:50:02
【问题描述】:

我正在为 Windows 运行 make。 (choco install make)

在我尝试构建一个 docker 容器,特别是部署在 Amazon ECS 上之前,几乎一切都运行良好......

ECS 部署过程的一部分是您从 AWS 获取登录信息 aws ecr get-login 这将返回一个包含命令的字符串,看起来像 docker login -u AWS -p AQEC...HGZSSUMX4ftIpo8gY2 -e none https://123456789.dkr.ecr.us-east-1.amazonaws.com

如果我只是从 shell 运行它,我会复制输出并将其传递到命令行并运行 - 但我试图将它放入我的 makefile 中,所以我有 @ECS_LOGIN =$(shell aws ecr get-login)

然后我尝试在下一行执行它 $(ECS_LOGIN)

这就是我得到的地方
process_begin: CreateProcess(NULL, ECS_LOGIN =docker login -u AWS -p AQEC...HGZSSUMX4ftIpo8gY2 -e none https://123456789.dkr.ecr.us-east-1.amazonaws.com, ...) failed. make (e=2): The system cannot find the file specified. make: *** [docker-deploy] Error 2

从研究其他问题来看,这似乎是从 Windows 运行时的路径问题 Makefile error make (e=2): The system cannot find the file specified

但是在我的aws ecr get-login 之前的 docker 命令可以正常工作 即
docker build
所以它似乎特定于从变量中运行命令

那么我如何从 make 运行此命令并解析路径?

完整配方
docker-deploy: docker-build @ECS_LOGIN =$(shell aws ecr get-login) $(ECS_LOGIN) docker tag mytag:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/mytag:latest docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/mytag:latest

【问题讨论】:

    标签: windows makefile


    【解决方案1】:

    首先,您需要确定要使用哪个工具来运行“aws ecr get-login”命令。在您的配方中,Make 运行它(并且您将结果分配给 shell 变量而不引用多字值,但我猜 Windows shell 可以使用它吗?)。在下一行中,您尝试引用 shell 变量,但忘记用美元引用美元符号,因此无论调用配方时 ECS_LOGIN 的值是什么(这可能是什么都没有)。

    也许首先将第一行 (ECS_LOGIN=$(shell aws ecr get-login)) 移出 shell 配方,看看是否有帮助:

    ECS_LOGIN =$(shell aws ecr get-login)
    docker-deploy: docker-build
        @$(ECS_LOGIN)
        docker tag mytag:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/mytag:latest
        docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/mytag:latest
    

    【讨论】:

    • 谢谢 - 将变量集放在配方之外似乎可以解决问题
    【解决方案2】:

    您的 makefile 对 make 变量与 shell 变量以及如何调用配方感到困惑;见迈克尔的回答。

    如果是我,我根本不会费心使用变量;你有这样做的理由吗?

    你可以使用:

    docker-deploy: docker-build
            @$(shell aws ecr get-login)
            docker tag mytag:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/mytag:latest
            docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/mytag:latest
    

    这会起作用,但有点奇怪:在配方中运行shell 函数会令人困惑,因为你已经在 shell 中,所以另一种方法是完全使用配方 shell 并避免 make 的 shell功能:

    docker-deploy: docker-build
            @eval $$(aws ecr get-login)
            docker tag mytag:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/mytag:latest
            docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/mytag:latest
    

    【讨论】: