使用jq使用空格导出环境变量

Ric*_*ker 0 bash environment-variables jq

所以,我正在尝试导出一个来自api的环境变量,它返回json值.想使用jq只做一个衬垫,但如果值有空格我不能让它工作

尝试不包围引号中的值

/app/src $ $(echo '{"params":[{ "Name":"KEY","Value":"value with space"}]}' | jq
 -r '.params[] | "export " + .Name + "=" + .Value')
/app/src $ printenv KEY
value
/app/src $ 
Run Code Online (Sandbox Code Playgroud)

接下来,我尝试将值包装在引号中

/app/src $ $(echo '{"params":[{ "Name":"KEY","Value":"value with space"}]}' | jq
 -r '.params[] | "export " + .Name + "=\"" + .Value + "\""')
sh: export: space": bad variable name
/app/src $ 
Run Code Online (Sandbox Code Playgroud)

Cha*_*ffy 5

对于以下所有,我假设:

json='{"params":[{ "Name":"KEY","Value":"value with space"}]}'
Run Code Online (Sandbox Code Playgroud)

它可以完成eval,但只有你信任你的输入.

这可能看起来像:

eval "$(jq -r '.params[] | "export \(.Name | @sh)=\(.Value | @sh)"' <<<"$json")"
Run Code Online (Sandbox Code Playgroud)

@sh在内置jq逃逸内容要eval在bash -safe,并且eval然后调用确保内容经过所有解析级(在数据所以文字引号由发射jq成为句法).


更好的形式是生成NUL分隔的键/值列表......

build_kv_nsv() {
  jq -j '.params[] |
    ((.Name | gsub("\u0000"; "")),
     "\u0000",
     (.Value | gsub("\u0000"; "")),
     "\u0000")'
}
Run Code Online (Sandbox Code Playgroud)

...并填充一个关联数组......

declare -A content_received=( )
while IFS= read -r -d '' name && IFS= read -r -d '' value; do
  content_received[$name]=$value
done < <(build_kv_nsv <<<"$json")

# print the value of the populated associative array
declare -p content_received
Run Code Online (Sandbox Code Playgroud)

...或者使用带有前缀的命名空间来保证安全.

while IFS= read -r -d '' name && IFS= read -r -d '' value; do
  printf -v "received_$name" %s "$value" && export "received_$name"
done < <(build_kv_nsv <<<"$json")

# print names and values of our variables that start with received_
declare -p "${!received_@}" >&2
Run Code Online (Sandbox Code Playgroud)