Where exactly am I going wrong?
if [ $_idx -ge 14 -a $_idx -le $_end ]
The entire approach of parsing output by counting specific numbers of non-blank lines from the beginning and end. It is highly fragile, and obviously cannot cope with a different number of lines being returned before and after the ones you wanted.
Your provided input from duplicity has a lot more than 3 more than your expected 14 non-empty lines before the wanted data. One possibility is this input could have been a mix of stdout and stderr, whereas your code only reads stdout. However, I note there are 14 non-blank lines excluding the Copying
lines. As the input from duplicity also does not match the expected or actual output for the backup dates, I suspect there were only three Copying
lines in the actual input for your example.
If so, and if the format of the output is otherwise the same in all cases, your code might work if duplicity collection-status
is run twice without a new backup in between. But this also assumes there will be no new surprises in the output, including possible changes in any future version of duplicity.
Rather than counting, scan for lines beginning 'Full' or 'Incremental' instead. Extra output is less likely and it's also much simpler.
It's an important habit to always double quote "$variables"
except when you are intentionally word breaking (e.g. your IFS lines). If you only do the minimum, it's easy to be caught out by unexpected word breaking later on future input you hadn't originally anticipated.
Also, the bash built-in select
(see help select
) is an easy way to handle menus.
# 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")