背景關系:我有一個場景,我需要將備份從一個系統復制到另一個系統。我希望備份串列是可配置的,所以我在腳本本身中采用了 JSON 方法。
該串列包含密鑰(要在輸出中顯示的備份名稱)、ssh 的用戶以及從中獲取備份的路徑。
例子:
backups_to_perform='[
{
"key": "key1",
"user": "user1",
"path": "path1"
},
{
"key": "key2",
"user": "user2",
"path": "path2"
},
{
"key": "key3",
"user": "user3",
"path": "path3"
},
]'
我使用 JSON 的原因是我想要一個類似于 python 字典的結構,因為關聯陣列只能有key:pair, 而不是key{key:pair; key:pair}(如果我錯了,請糾正我)
這就是我決議 JSON 的方式:
while read -r backup; do
IFS=, read -r key user path <<<"$(jq -cr '"\(.key),\(.user),\(.path)"' <<<"$backup")"
rsync_backup "$key" "$user" "$path"
done < <(jq -cr '.[]' <<<"$backups_to_perform")
rsync_backup 只是一個執行接受這些引數的 rsync 的函式。
可能有更好的解決方案來實作我想要的備份副本,但我想改進這種型別的代碼,以便我下次可以更好地應用它。
我的問題是,當 JSON 很大時,這似乎需要一些時間(我已經在這篇文章中減少到 3 個)。看起來我決議 JSON 的方式非常復雜,但我無法以任何其他方式作業。
我呼叫jq一次來饋送回圈,然后在每次迭代時再次呼叫它,這可能很糟糕。
uj5u.com熱心網友回復:
更新
需要考慮的幾點:
- 您可以避免
jq在while回圈內使用:
#!/bin/bash
while IFS=',' read -r key user path
do
# rsync_backup "$key" "$user" "$path"
echo "key=$key user=$user path=$path"
done < <(
jq -cr '.[] | "\(.key),\(.user),\(.path)"' <<< "$backups_to_perform"
)
您應該防止 JSON 中的拼寫錯誤導致
null值(例如,如果您鍵入"usr":而不是"user":)。您應該允許在
"key":and 中使用逗號,以及在 中使用"user":任何字符(除了NULL BYTE)"path":。
考慮到所有這些,我會選擇 TSV 格式作為jq輸出:
#!/bin/bash
# safety check
if $(jq 'any(.[]; .key and .user and .path | not)' <<< "$backups_to_perform")
then
jq -c '.[] |select(.key and .user and .path |not)' <<< "$backups_to_perform" |
awk -v prefix="[WARNING] missing attribute in record: " '{print prefix $0}'
fi
# doing the backups
while IFS=$'\t' read -r key user path
do
# unescape TSV values
printf -v key %b "$key"
printf -v user %b "$user"
printf -v path %b "$path"
# rsync_backup "$key" "$user" "$path"
echo "key=$key user=$user path=$path"
done < <(
jq -r '.[] | select(.key and .user and .path) | [.key,.user,.path] | @tsv' <<< "$backups_to_perform"
)
您可以使用以下輸入對其進行測驗:
IFS='' read -r -d '' backups_to_perform <<'EOJ'
[
{
"__comment__": "comma in key value",
"key": "key,1",
"user": "user1",
"path": "path1"
},
{
"__comment__": "newline in key value",
"key": "key\n2",
"user": "user2",
"path": "path2"
},
{
"__comment__": "mispelled user attribute",
"key": "key3",
"usr": "user3",
"path": "path3"
},
{
"__comment__": "path containing ascii range [0x01-0x7f]",
"key": "key4",
"user": "user4",
"path": "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()* ,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f"
}
]
EOJ
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/404630.html
標籤:
