如何扩展变量值以构建一个

时间:2019-03-07 06:08:15

标签: jq

对不起,如果其中包含此内容,请按照这些原则寻找30-60分钟的时间。我确定我只是错过了一些东西!总计jq nub!

基本上,我正在尝试执行动态的pick操作。我的思维过程是做这样的事情:

pickJSON() {
  getSomeJSON | jq -r --arg PICK "$1" '{ $PICK }'
}

pickJSON "foo, bar"

但这会产生

{ "PICK": "foo, bar" }

有没有一种方法可以要求它扩展外壳样式?


所需结果:

pickJSON() {
  getSomeJSON | jq -r --arg PICK "$1" '{ $PICK }'
  # perhaps something like...
  # getSomeJSON | jq -r --arg PICK "$1" '{ ...$PICK }'
}

pickJSON "foo, bar"
{ "foo": "foovalue", "bar": "barvalue" }
  

请注意,我是jq的新手,我只是简化了我的工作-如果语法被破坏,这就是为什么:-D我的实际工具中有一些管道,如果我没有,它确实可以工作尝试从中选择值。

1 个答案:

答案 0 :(得分:0)

经过一个相当长的实验阶段,尝试完成这项工作后,我终于提出了一种可行且可靠的解决方案,而没有使用eval可能带来的令人不安的缺陷。

为了更好地突出整体最终解决方案,我在下面提供了我目前正在使用的更多处理方法:

目标

  1. AWS Secrets Manager

  2. 中获取秘密
  3. 解析返回的JSON,如下所示:

{
  "ARN": "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
  "Name": "MyTestDatabaseSecret",
  "VersionId": "EXAMPLE1-90ab-cdef-fedc-ba987EXAMPLE",
  "SecretString": "{\n  \"username\":\"david\",\n  \"password\":\"BnQw&XDWgaEeT9XGTT29\"\n}\n",
  "VersionStages": [
    "AWSPREVIOUS"
  ],
  "CreatedDate": 1523477145.713
}
  1. 对收到的JSON字符串进行一些修改,并仅从秘密中选择静态请求的密钥

  2. 设置这些值并将其导出为环境变量

脚本

# Capture a AWS Secret from secretsmanager, parse the JSON and expand the given
# variables within it to pick them from the secret and return given portion of 
# the secret requested.
# @note similar to _.pick(obj, ["foo", "bar"])
getKeysFromSecret() {
  aws secretsmanager get-secret-value --secret-id "$1" \
    | jq -r '.SecretString | fromjson' \
    | jq -r "{ $2 }"
}

# Uses `getKeysFromSecret` to capture the requested keys from the secret
# then transforms the JSON into a string that we can read and loop through
# to set each resulting value as an exported environment variable.
#
## Transformation Flow:
#   { "foo": "bar", "baz": "qux" } 
# --> 
#   foo=bar
#   baz=qux 
# --> 
#   export foo=bar
#   export baz=qux
exportVariablesInSecret() {
  while IFS== read -r key value; do
    if [ -n "$value" ]; then 
      export "${key}"="${value}";
    fi
  done < <(getKeysFromSecret "$1" "$2" | jq -r 'to_entries | .[] | .key + "=" + .value')
}


示例JSON

{
  ...othervalues
  "SecretString": "{\"foo\": \"bar\", \"baz\": \"qux\"}"
}

用法示例

exportVariablesInSecret MY_SECRET "foo, bar"
echo $foo
# bar

一些注释/上下文

  1. 这是为了将一组给定的值设置为变量,这样我们就不只是将整个任意JSON对象设置为变量,如果有人向其中添加“ path”之类的值,可能会导致问题/阴影一个秘密

  2. 一个关键目标是绝对不要使用eval来防止可能的注入情况。太容易注入其他东西了。

  3. 很高兴看到是否有人有更好的方法来完成此任务。我看到很多人建议使用declare,但这只会将var设置为局部函数范围,因此它实际上是无用的。


感谢@cas https://unix.stackexchange.com/a/413917/308550使我步入正轨!