【问题标题】:Why jq does not see environment variables when run in script?为什么 jq 在脚本中运行时看不到环境变量?
【发布时间】:2020-06-30 06:53:04
【问题描述】:

我有以下 JSON 文件:

{
"1":
 {
   "media_content":"test3.xspf"
 },
"2":
 {
   "media_content":"test3.xspf"
 }
}

在终端中,使用 bash 作为 shell,我可以执行以下命令:

export schedules="1"
echo $(jq '.[env.schedules]["media_content"]' json_file.json)

这会导致输出:

test3.xspf

所以它按预期工作,但是当我将该 jq 命令放在脚本中并运行它时,它只返回 null。 我确实回显了时间表的值,以确保脚本中的值不为空,这没关系:

echo $schedules

但是我没有找到原因,为什么这个命令直接在shell中运行时有效,而在脚本中运行时无效。

我通过以下方式运行脚本:

bash script.sh
./script.sh

PS:是的,我确实提供了执行权限:chmod +x script.sh

提示:env.schedules 表示环境变量 'schedules',我确实在调用 jq 之前确保在脚本中分配了它。

编辑:我现在发布一个完整的脚本,指定文件树。

有一个目录包含:

  • script.sh
  • json_file.json
  • 静态.json

script.sh:

export zone=$(cat static.json | jq '.["1"]');

echo "json block: "$zone

export schedules="$(echo $zone | jq '.schedules')"

echo "environment variable: "$schedules
export media_content=$(jq '.[env.schedules]["media_content"]' json_file.json)

echo "What I want to get: \"test3.xspf\""
echo "What I get: "$media_content

json_file.json:

{
"1":
 {
   "media_content":"test3.xspf"
 },
"2":
 {
   "media_content":"test3.xspf"
 }
}

静态.json:

{
"1":
 {
   "x": "0",
   "y": "0",
   "width": "960",
   "height": "540",
   "schedules":"1"
 }
}

如果我运行脚本,它会显示:

json block: { "x": "0", "y": "0", "width": "960", "height": "540", "schedules": "1" }
environment variable: "1"
What I want to get: "test3.xspf"
What I get: null

如果我对变量进行硬编码:

export schedules="1"   

问题不再出现

【问题讨论】:

  • 你能发布脚本吗?你是如何运行它的?
  • 我更新了:bash script.sh 或:./script.sh 该脚本由使用 jq 的两行组成。
  • echo $(..) 是对回显的无用使用。就像echo $(echo $(echo $(...))))。只需输入jq,无需回显。
  • @Alexandru-MihaiManolescu 根据您发布的内容,您的代码应该可以工作。请发布确切的脚本及其内容。
  • @Maroun 谢谢。我删除了所有多余的部分并保留了这两行(整个软件包含大约 9 个长的 shell 脚本,发布所有内容会带来更多的混乱)。我重新考虑发布更多内容,但我认为这些部分不相关:((再次感谢您

标签: bash shell jq


【解决方案1】:

问题很简单。
这不是 jq 的错。
这是将计划的值通过管道传送到下一个命令的不正确方式。

您必须删除围绕变量值的 "s,添加使用 sed 执行此操作的第二个命令:

    export schedules="$(echo $zone | jq '.schedules')"
    schedules=$( echo $schedules | sed s/\"//g )

长答案 让我们看看:
这里 schedules 是一个字符串,echo 显示它的值为 1:

export schedules="1" ; echo $schedules 

这里虽然没有提到双引号:

export schedules=1 ; echo $schedules 

但由此产生的结果也会产生额外的“s:

export schedules=$(echo $zone | jq '.schedules')

如果你现在打印它,你会看到额外的“s:

echo $schedules # "1"

所以只需从值中删除 "s:

schedules=$( echo $schedules | sed s/\"//g )

【讨论】:

  • 这不是一个“伪字符串”,它是一个字符串,句号。 shell中的所有值都是字符串;引号是关于转义具有特殊含义的字符,而不是指定数据类型。不过,更好的解决方案是让jq 输出一个原始字符串,而不是使用export schedules=$(echo "$zone" | jq -r '.schedules') 引用的JSON 字符串。
猜你喜欢
  • 2014-09-24
  • 2015-02-28
  • 2022-08-23
  • 2019-03-25
  • 2017-07-26
  • 2015-11-06
  • 2012-10-08
  • 1970-01-01
  • 2012-12-11
相关资源
最近更新 更多