想知道我是否可以在这里解析命令的输出 duplicity collection-status MYPATH
我的最终目标是构建一个“恢复”脚本,该脚本将使用此命令并构建一个可选择的备份列表以从中恢复。
现在,我的代码如下:
# get the backups information
_t=`duplicity collection-status $1`
# split the collection based on new lines
IFS=$'\n' _arr=($_t)
# find the length of the array
_arr_len=${#_arr[@]}
# we only want the last set of lines, minus the last 2 lines
_end=`expr $_arr_len - 2`
# loop over our resulting set and echo out the line
_idx=1
_menu_idx=1
_ret_arr=()
# make sure there are actually backups created
if [[ -z ${_arr[14]} ]]; then
# it doesnt exist, show a message and exit
echo
echo '--------------------------------------------------------------------';
echo 'There are no backups for that account/app'
echo 'Please create the account, and make sure it matches the restore'
echo 'Account and App names'
echo '--------------------------------------------------------------------';
echo
exit 1;
fi;
echo
echo '--------------------------------------------------------------------';
echo "- Select a restore point: "
for _l in ${_arr[@]}; do
if [ $_idx -ge 14 -a $_idx -le $_end ]; then
IFS=$' ' _temp_arr=($_l)
_d_string=${_temp_arr[1]}" "${_temp_arr[2]}" "${_temp_arr[3]}" "${_temp_arr[4]}" "${_temp_arr[5]}
_ret_arr+=( "$_d_string" )
# Tue Aug 27 10:59:43 2019
echo $_menu_idx") "$_d_string;
((_menu_idx=_menu_idx+1))
fi;
((_idx=_idx+1))
done
read n
# get the value of the selected item
_t=${_ret_arr[$n-1]};
# make sure the selection is valid
if [[ -z $_t ]]; then
echo "You selected an invalid restore point. Please try again"
exit 1;
fi;
echo
# convert the selected value to a epoch date and return it
_ret_date=$(date -d "${_t}" +"%s");
虽然这似乎对我的目的有用,但我在几个不同的服务器上发现我在前后都有一些“额外”的文本,所以列表并不总是只是备份点。示例输出的结构有点像这样:
root@sp-stage1:~# duplicity collection-status $_dest/$_host/apps/aats/aats/
Synchronizing remote metadata to local cache...
Copying duplicity-full-signatures.20190903T134927Z.sigtar.gz to local cache.
Copying duplicity-full.20190903T134927Z.manifest to local cache.
Copying duplicity-inc.20190903T134927Z.to.20190903T162118Z.manifest to local cache.
Copying duplicity-inc.20190903T162118Z.to.20190904T050005Z.manifest to local cache.
Copying duplicity-inc.20190904T050005Z.to.20190905T050004Z.manifest to local cache.
Copying duplicity-inc.20190905T050004Z.to.20190906T050005Z.manifest to local cache.
Copying duplicity-inc.20190906T050005Z.to.20190907T050005Z.manifest to local cache.
Copying duplicity-inc.20190907T050005Z.to.20190908T050004Z.manifest to local cache.
Copying duplicity-new-signatures.20190903T134927Z.to.20190903T162118Z.sigtar.gz to local cache.
Copying duplicity-new-signatures.20190903T162118Z.to.20190904T050005Z.sigtar.gz to local cache.
Copying duplicity-new-signatures.20190904T050005Z.to.20190905T050004Z.sigtar.gz to local cache.
Copying duplicity-new-signatures.20190905T050004Z.to.20190906T050005Z.sigtar.gz to local cache.
Copying duplicity-new-signatures.20190906T050005Z.to.20190907T050005Z.sigtar.gz to local cache.
Copying duplicity-new-signatures.20190907T050005Z.to.20190908T050004Z.sigtar.gz to local cache.
Last full backup date: Tue Sep 3 09:49:27 2019
Collection Status
-----------------
Connecting with backend: BackendWrapper
Archive dir: /home/ubuntu/.cache/duplicity/6a9fb8e3df936035e1be5ede96c0d7a7
Found 0 secondary backup chains.
Found primary backup chain with matching signature chain:
-------------------------
Chain start time: Tue Sep 3 09:49:27 2019
Chain end time: Sun Sep 8 01:00:04 2019
Number of contained backup sets: 7
Total number of contained volumes: 8
Type of backup set: Time: Num volumes:
Full Tue Sep 3 09:49:27 2019 2
Incremental Tue Sep 3 12:21:18 2019 1
Incremental Wed Sep 4 01:00:05 2019 1
Incremental Thu Sep 5 01:00:04 2019 1
Incremental Fri Sep 6 01:00:05 2019 1
Incremental Sat Sep 7 01:00:05 2019 1
Incremental Sun Sep 8 01:00:04 2019 1
-------------------------
No orphaned or incomplete backup sets found.
在这个具体的例子中,产生的菜单是这样的:
--------------------------------------------------------------------
- Select a restore point:
1) of contained backup sets: 8
2) number of contained volumes: 9
3) of backup set: Time: Num
4) Tue Sep 3 09:49:27 2019
5) Tue Sep 3 12:21:18 2019
6) Wed Sep 4 01:00:05 2019
7) Thu Sep 5 01:00:04 2019
8) Fri Sep 6 01:00:05 2019
9) Sat Sep 7 01:00:05 2019
10) Sun Sep 8 01:00:04 2019
11) Sun Sep 8 09:33:26 2019
当它真的应该是:
--------------------------------------------------------------------
- Select a restore point:
1) Tue Sep 3 09:49:27 2019
2) Tue Sep 3 12:21:18 2019
3) Wed Sep 4 01:00:05 2019
4) Thu Sep 5 01:00:04 2019
5) Fri Sep 6 01:00:05 2019
6) Sat Sep 7 01:00:05 2019
7) Sun Sep 8 01:00:04 2019
8) Sun Sep 8 09:33:26 2019
(是的,9 月 8 日的双重备份是正确的......现在)
所以......我一定是做错了显示那些额外的几行......我该如何解决这个问题,我到底哪里出错了?
(如果我可以简单地传递一个--json
标志会容易得多,但到目前为止还没有实现......)
我到底哪里错了?
if [ $_idx -ge 14 -a $_idx -le $_end ]
通过从开头和结尾计算特定数量的非空行来解析输出的整个方法。它非常脆弱,显然无法处理在您想要的行之前和之后返回的不同数量的行。
您从 duplicity 提供的输入比所需数据之前的预期 14 行非空行多 3 行。一种可能性是此输入可能是 stdout 和 stderr 的混合,而您的代码仅读取 stdout。但是,我注意到有 14 条非空行不包括这些Copying
行。由于 duplicity 的输入也与备份日期的预期或实际输出不匹配,我怀疑Copying
您的示例的实际输入中只有三行。
如果是这样,并且如果输出的格式在所有情况下都相同,则您的代码可能会在duplicity collection-status
运行两次而中间没有新备份的情况下工作。但这也假设输出中不会有新的惊喜,包括任何未来版本的双重性可能发生的变化。
而不是计数,而是扫描以“完整”或“增量”开头的行。额外输出的可能性较小,而且也简单得多。
除非您有意断字(例如您的 IFS 行),否则始终使用双引号是一个重要的习惯"$variables"
。如果您只做最低限度的工作,很容易在您最初没有预料到的未来输入中被意外的断字所吸引。
此外,内置的 bash select
(请参阅参考资料help select
)是一种处理菜单的简单方法。
# get the backups information
_t=`duplicity collection-status "$1"`
# split the collection based on new lines
IFS=$'\n' _arr=($_t)
# loop over our resulting set and select lines
_ret_arr=()
for _l in "${_arr[@]}"; do
IFS=$' ' _temp_arr=($_l)
if [ Full = "${_temp_arr[0]}" -o Incremental = "${_temp_arr[0]}" ]; then
_d_string="${_temp_arr[1]} ${_temp_arr[2]} ${_temp_arr[3]} ${_temp_arr[4]} ${_temp_arr[5]}"
_ret_arr+=( "$_d_string" )
fi;
done
echo
echo '--------------------------------------------------------------------';
# make sure there are actually backups created, i.e. at least one line matched
if [[ -z "${_ret_arr[0]}" ]]; then
# it doesnt exist, show a message and exit
echo 'There are no backups for that account/app'
echo 'Please create the account, and make sure it matches the restore'
echo 'Account and App names'
echo '--------------------------------------------------------------------';
echo
exit 1;
fi
echo "- Select a restore point: "
select _t in "${_ret_arr[@]}"; do
# will keep asking until valid value given
[ -n "$_t" ] && break
done
echo
# convert the selected value to a epoch date and return it
_ret_date=$(date -d "${_t}" +"%s")
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句