You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Makefile中将jq命令输出赋值给变量后结果为空的解决方法

问题根因

你遇到的变量为空问题由两个核心错误导致:

  • 变量引用语法混用:你在shell命令逻辑中定义的UPDATE_ENVVARS是shell进程内的局部变量,但echo输出时使用了Makefile变量语法${UPDATE_ENVVARS}。Make在执行命令前会优先展开所有自身语法的变量引用,由于你从未在Makefile上下文定义过同名变量,该引用会被直接替换为空字符串,最终传给shell执行的就是echo "",自然没有输出。
  • Make的shell执行机制问题:Make默认会为target下的每一行独立命令启动单独的shell进程,就算你修正了变量引用,如果后续使用变量的命令没有和赋值命令放在同一个shell会话中,上一个进程退出时定义的shell变量会直接销毁,后续命令无法读取到值。
修复方法

方案1:保留原有续行写法,修正变量引用

只需要把echo位置的Make风格变量引用改成shell变量引用即可,注意shell变量在Makefile中需要用双美元符号$$转义,告诉Make不要提前展开该变量,直接交给shell解析。修正后的target写法如下:

update-env:
    echo "{ \"Variables\":${ENV_VALUE}}" > ./new_env.json && \
    UPDATE_ENVVARS=$$(jq -s '.[0] as $$a |.[1] as $$b | $$a * $$b' old_env.json new_env.json | jq -c . ) && \
    echo "$$UPDATE_ENVVARS"
    # 后续要复用该变量的命令,必须通过&& \ 续行和上面的命令保持在同一个shell会话中,例如:
    # && curl -X POST -H "Content-Type: application/json" -d "$$UPDATE_ENVVARS" https://your-api.com

额外优化:你的jq合并逻辑可以简化,不需要两次调用jq、也不需要显式定义临时变量,直接写成jq -s '.[0] * .[1]' -c old_env.json new_env.json就能得到同样的压缩合并结果。

方案2:开启ONESHELL模式简化写法(推荐)

如果你使用的是GNU Make 3.82及以上版本,可以在Makefile开头开启.ONESHELL特性,同一个target下的所有命令会默认在同一个shell进程中执行,不需要写大量续行符,可读性更高:

# 放在Makefile顶部即可
.ONESHELL:
SHELL := /bin/bash

update-env:
    echo "{ \"Variables\":${ENV_VALUE}}" > ./new_env.json
    UPDATE_ENVVARS=$$(jq -s '.[0] * .[1]' -c old_env.json new_env.json)
    echo "$$UPDATE_ENVVARS"
    # 后续命令直接写在这里即可,直接用$$UPDATE_ENVVARS就能读取到合并后的JSON值
    # other_command "$$UPDATE_ENVVARS"

修正后再执行你原来的make调用命令,就能正常输出合并后的JSON内容,后续命令也可以正常复用该变量。

内容的提问来源于stack exchange,提问作者azngunit81

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 06:36:25