我正在尝试使用 json 将变量拉入循环
Im trying to use json to pull a variable into a loop
我正在复制json?从两个网站尝试实现我的目标
https://softwaredevelopmentstuff.com/2017/05/02/downloading-an-aws-glacier-archive-step-by-step/
https://gist.github.com/veuncent/ac21ae8131f24d3971a621fac0d95be5
这个有效:
#!/bin/bash
file='/home/nat/Documents/glacier_access/output.json'
if [[ -z ${AWS_ACCOUNT_ID} ]] || [[ -z ${AWS_REGION} ]] || [[ -z ${AWS_VAULT_NAME} ]]; then
echo "Please set the following environment variables: "
echo "AWS_ACCOUNT_ID"
echo "AWS_REGION"
echo "AWS_VAULT_NAME"
exit 1
fi
archive_ids=$(jq .ArchiveList[].ArchiveId < $file)
for archive_id in ${archive_ids}; do
echo "Downloading Archive: ${archive_id}"
aws glacier delete-archive --archive-id=${archive_id} --vault-name ${AWS_VAULT_NAME} --account-id ${AWS_ACCOUNT_ID} --region ${AWS_REGION}
done
就像这样:
# file to loop action on archives
#!/bin/bash
file='/home/nat/Documents/glacier_access/output.json'
if [[ -z ${AWS_ACCOUNT_ID} ]] || [[ -z ${AWS_REGION} ]] || [[ -z ${AWS_VAULT_NAME} ]]; then
echo "Please set the following environment variables: "
echo "AWS_ACCOUNT_ID"
echo "AWS_REGION"
echo "AWS_VAULT_NAME"
exit 1
fi
archive_ids=$(jq .ArchiveList[].ArchiveId < $file)
for archive_id in ${archive_ids}; do
echo "Downloading Archive: ${archive_id}"
aws glacier initiate-job \
--account-id 510422384120\
--vault-name ebony-backup \
--job-parameters '{
"Type": "archive-retrieval",
"Description": "Download all my archives",
"ArchiveId": "w0GUthLDLDR6NL1z4c53M1IFktxBCrW_qZ2Qm_",
}'
done
但是我不能在循环中引用变量
所以这不起作用:
"ArchiveId": "${archive_id}"
也不是这个:
"ArchiveId": "{archive_id}"
需要注意的重要一点是必须从作业参数部分引用 ArcihiveID。
感谢收到的任何帮助。我假设这是一个 JSON 问题?
您关于不能在循环中使用变量的说法是错误的。您已经使用 echo "Downloading Archive: ${archive_id}"
证明了这一点。这意味着问题实际上出在循环的第二个命令上。
具体来说,问题在于您构建用作 --job-parameters
参数的字符串。单引号中的所有内容都是准确生成的,因此您生成了字符串
{
"Type": "archive-retrieval",
"Description": "Download all my archives",
"ArchiveId": "${archive_id}"
}
接下来有四种解决方案。
使用双引号字符串从 shell 创建 JSON
--job-parameters "{
\"Type\": \"archive-retrieval\",
\"Description\": \"Download all my archives\",
\"ArchiveId\": \"$archive_id\"
}"
总的来说,我讨厌从 shell 脚本生成代码的方法。然而,在这种情况下它是安全的,因为 id 完全由单词字符组成。不过,我们确实以很多反斜杠结尾。
使用 here-doc
从 shell 创建 JSON
--job-parameters <<EOS
{
"Type": "archive-retrieval",
"Description": "Download all my archives",
"ArchiveId": "$archive_id"
}
EOS
这仍在从 shell 脚本生成代码。但是通过使用 here-doc,"
不再特殊,因此无需转义它们。
使用 jq
创建 JSON
--job-parameters "$(
jq -n --arg archive_id "$archive_id" '
{
"Type": "archive-retrieval",
"Description": "Download all my archives",
"ArchiveId": $archive_id
}
'
)"
请注意,这在 jq
程序中使用了 jq
变量 $archive_id
(使用 --arg
创建),因此没有引号。 jq
将为它生成正确的 JSON 字符串文字(如果包含特殊字符,如 "
,则包括它)。
这更简洁,即使 archive_id 包含特殊字符也能正常工作。有点慢,每次都要启动jq
使用 jq 的单个实例创建 JSON
这解决了必须多次启动 jq 的问题。
jq -c '
.ArchiveList[] |
{
"Type": "archive-retrieval",
"Description": "Download all my archives",
"ArchiveId": .ArchiveId
}
' "$file" |
while read -r job; do
aws glacier initiate-job \
--account-id 510422384120 \
--vault-name ebony-backup \
--job-parameters "$job"
done
请注意,存档 ID 后不应有逗号。 JSON.
中不允许尾随逗号
我正在复制json?从两个网站尝试实现我的目标
https://softwaredevelopmentstuff.com/2017/05/02/downloading-an-aws-glacier-archive-step-by-step/
https://gist.github.com/veuncent/ac21ae8131f24d3971a621fac0d95be5
这个有效:
#!/bin/bash
file='/home/nat/Documents/glacier_access/output.json'
if [[ -z ${AWS_ACCOUNT_ID} ]] || [[ -z ${AWS_REGION} ]] || [[ -z ${AWS_VAULT_NAME} ]]; then
echo "Please set the following environment variables: "
echo "AWS_ACCOUNT_ID"
echo "AWS_REGION"
echo "AWS_VAULT_NAME"
exit 1
fi
archive_ids=$(jq .ArchiveList[].ArchiveId < $file)
for archive_id in ${archive_ids}; do
echo "Downloading Archive: ${archive_id}"
aws glacier delete-archive --archive-id=${archive_id} --vault-name ${AWS_VAULT_NAME} --account-id ${AWS_ACCOUNT_ID} --region ${AWS_REGION}
done
就像这样:
# file to loop action on archives
#!/bin/bash
file='/home/nat/Documents/glacier_access/output.json'
if [[ -z ${AWS_ACCOUNT_ID} ]] || [[ -z ${AWS_REGION} ]] || [[ -z ${AWS_VAULT_NAME} ]]; then
echo "Please set the following environment variables: "
echo "AWS_ACCOUNT_ID"
echo "AWS_REGION"
echo "AWS_VAULT_NAME"
exit 1
fi
archive_ids=$(jq .ArchiveList[].ArchiveId < $file)
for archive_id in ${archive_ids}; do
echo "Downloading Archive: ${archive_id}"
aws glacier initiate-job \
--account-id 510422384120\
--vault-name ebony-backup \
--job-parameters '{
"Type": "archive-retrieval",
"Description": "Download all my archives",
"ArchiveId": "w0GUthLDLDR6NL1z4c53M1IFktxBCrW_qZ2Qm_",
}'
done
但是我不能在循环中引用变量
所以这不起作用:
"ArchiveId": "${archive_id}"
也不是这个:
"ArchiveId": "{archive_id}"
需要注意的重要一点是必须从作业参数部分引用 ArcihiveID。
感谢收到的任何帮助。我假设这是一个 JSON 问题?
您关于不能在循环中使用变量的说法是错误的。您已经使用 echo "Downloading Archive: ${archive_id}"
证明了这一点。这意味着问题实际上出在循环的第二个命令上。
具体来说,问题在于您构建用作 --job-parameters
参数的字符串。单引号中的所有内容都是准确生成的,因此您生成了字符串
{
"Type": "archive-retrieval",
"Description": "Download all my archives",
"ArchiveId": "${archive_id}"
}
接下来有四种解决方案。
使用双引号字符串从 shell 创建 JSON
--job-parameters "{
\"Type\": \"archive-retrieval\",
\"Description\": \"Download all my archives\",
\"ArchiveId\": \"$archive_id\"
}"
总的来说,我讨厌从 shell 脚本生成代码的方法。然而,在这种情况下它是安全的,因为 id 完全由单词字符组成。不过,我们确实以很多反斜杠结尾。
使用 here-doc
从 shell 创建 JSON --job-parameters <<EOS
{
"Type": "archive-retrieval",
"Description": "Download all my archives",
"ArchiveId": "$archive_id"
}
EOS
这仍在从 shell 脚本生成代码。但是通过使用 here-doc,"
不再特殊,因此无需转义它们。
使用 jq
创建 JSON --job-parameters "$(
jq -n --arg archive_id "$archive_id" '
{
"Type": "archive-retrieval",
"Description": "Download all my archives",
"ArchiveId": $archive_id
}
'
)"
请注意,这在 jq
程序中使用了 jq
变量 $archive_id
(使用 --arg
创建),因此没有引号。 jq
将为它生成正确的 JSON 字符串文字(如果包含特殊字符,如 "
,则包括它)。
这更简洁,即使 archive_id 包含特殊字符也能正常工作。有点慢,每次都要启动jq
使用 jq 的单个实例创建 JSON
这解决了必须多次启动 jq 的问题。
jq -c '
.ArchiveList[] |
{
"Type": "archive-retrieval",
"Description": "Download all my archives",
"ArchiveId": .ArchiveId
}
' "$file" |
while read -r job; do
aws glacier initiate-job \
--account-id 510422384120 \
--vault-name ebony-backup \
--job-parameters "$job"
done
请注意,存档 ID 后不应有逗号。 JSON.
中不允许尾随逗号