【问题标题】:Unable to use jq arg as select filter无法使用 jq arg 作为选择过滤器
【发布时间】:2021-10-18 16:59:41
【问题描述】:

我正在尝试使用 jq 的 --arg 语法将变量从 shell 传递到 jq 过滤器。

如果我运行以下命令,jq 查询将按预期工作:

TS_SEC_START=1534574204 \
kubectl -n istio-system logs deployment/flagger --tail=50 | grep '^{' | \
jq --arg TS_SEC_START 1534574204 --arg SVC "${SERVICE_NAME}.${RELEASE_NAMESPACE}" \
-s 'map(select(.ts | (split(".")[0] + "Z") | fromdateiso8601 > ($TS_SEC_START | tonumber)) | select(.canary == "mysvc.prod"))'

-->

Found 3 pods, using pod/flagger-6dc6fd7d85-z294g
[
  {
    "level": "error",
    "ts": "2021-08-16T02:41:34.128Z",
    "caller": "controller/scheduler.go:163",
    "msg": "Canary mysvc.prod not found",
    "canary": "mysvc.prod",
    "stacktrace": "github.com/fluxcd/flagger/pkg/controller.(*Controller).advanceCanary\n\t/workspace/pkg/controller/scheduler.go:163\ngithub.com/fluxcd/flagger/pkg/controller.CanaryJob.Start.func1\n\t/workspace/pkg/controller/job.go:39"
  }
]

但是,当我尝试将 mysvc.prod 作为 arg 传递时,我收到 0 个响应。

TS_SEC_START=1534574204 SERVICE_NAME=mysvc RELEASE_NAMESPACE=prod \
kubectl -n istio-system logs deployment/flagger --tail=50 | grep '^{' | \
jq --arg TS_SEC_START 1534574204 --arg SVC "${SERVICE_NAME}.${RELEASE_NAMESPACE}" \
-s 'map(select(.ts | (split(".")[0] + "Z") | fromdateiso8601 > ($TS_SEC_START | tonumber)) | select(.canary == $SVC))'

我在这里尝试了一些不同的选项,例如.canary == "$SVC" 和 `.canary == "$SERVICE_NAME.$RELEASE_NAMESPACE" 但我无法让它工作。

我做错了什么?

-->

Found 3 pods, using pod/flagger-6dc6fd7d85-z294g
[]

【问题讨论】:

  • SERVICE_NAMERELEASE_NAMESPACE 究竟是如何设置的? SVC 可能没有您认为的确切值。 jq -n --arg SVC "a.b" '"a.b" == $f' 输出true
  • 我添加了sh 标签,因为我相信这个问题不仅仅是jq 问题,而是一个shell 脚本问题。

标签: sh jq


【解决方案1】:

一般来说,你不能这样做:

MYVAR=12345 printf "%s\n" "$MYVAR"

当您在 shell 命令前加上 MYVAR=12345 时,您正在修改传递给该进程的环境,在本例中为 printf。但是,$MYVAR 表达式在 shell 中展开,并且在 shell 中不存在 MYVAR 变量。

此外,当您像这样设置变量时,它们只会传递给该命令,而不是整个管道。

所以在这个例子中:

TS_SEC_START=1534574204 \
SERVICE_NAME=mysvc \
RELEASE_NAMESPACE=prod \
kubectl -n istio-system logs deployment/flagger --tail=50 | \
    grep '^{' | \
    jq \
        --arg TS_SEC_START 1534574204 \
        --arg SVC "${SERVICE_NAME}.${RELEASE_NAMESPACE}" \
        -s \
        '
          map(
            select(
              .ts |
              (split(".")[0] + "Z") |
              fromdateiso8601 > ($TS_SEC_START | tonumber)
            ) |
            select(.canary == $SVC)
          )
        '

这三个环境变量对kubectl 是可见的,其他什么都看不到。它们对 grepjq 不可见(尽管它们都没有首先寻找此类环境变量),并且它们在扩展这些命令时对 shell 本身不可见。

【讨论】:

    猜你喜欢
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多