web-dev-qa-db-ja.com

重複収集ステータス形式

コマンド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フラグを渡せばもっと簡単になりますが、それはまだ実装されていません...)

2
Kevin

どこが間違っているのですか?

if [ $_idx -ge 14 -a $_idx -le $_end ]

最初と最後から特定の数の空白以外の行を数えることによって出力を解析するアプローチ全体。これは非常に壊れやすく、明らかに、必要な行の前後に返される別の行数に対応できません。

重複から提供された入力には、必要なデータの前に予想される14個の空でない行よりも3行以上多くあります。 1つの可能性は、この入力がstdoutとstderrの混合であった可能性があるのに対して、コードはstdoutのみを読み取ることです。ただし、Copying行を除く14行の非空白行があることに注意します。 duplicityからの入力もバックアップ日付の予想または実際の出力と一致しないため、実際の入力ではCopying行が3つしかなかったと思います。

その場合、および出力の形式がそれ以外の場合はすべて同じである場合、間にduplicity collection-statusが2回実行され、その間に新しいバックアップがなければ、コードが機能する可能性があります。ただし、これは、将来のバージョンの複製の可能性のある変更を含め、出力に新たな驚きがないことも前提としています。

カウントするのではなく、「フル」または「インクリメンタル」で始まる行をスキャンしてください。追加の出力は可能性が低く、それもはるかに簡単です。

always二重引用符"$variables"は、意図的にWordを改行する場合(IFS行など)を除いて、重要な習慣です。最小限のことだけを行うと、当初予期していなかった将来の入力で後で予期しないWordが壊れることに簡単に気付かれます。

また、bash組み込みselecthelp 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")
1
Martin Thornton