Linuxでファイル名の一部として日付スタンプを含むファイルを削除するためのよりクリーンな方法


8

30日以上経過したMySQLダンプファイルをパージするという新しい要件があります。ファイルは「all-mysql-YYYYMMDD-HHMM.dump」の命名規則を使用しています。ファイルはSANマウントファイルシステムに配置されるため、復元は問題になりませんが、残念ながらドライブスペースが制限され、すぐにいっぱいになるため、頻繁に人間の介入が必要になります。

ファイル名の例

  • all-mysql-20130324-2330.dump
  • all-mysql-20130325-2330.dump
  • all-mysql-20130326-2330.dump

私の最初の考えは、-mtime +30を指定したバッチスクリプト内で「find」を使用することでしたが、変更時間は保証されず、古いアーカイブの一部はパージ日を回避できます:)

次のBASHスクリプトを作成しましたが、この操作を実行するためのよりクリーンな方法があることを望んでいました。

#!/bin/bash

STARTING_DIR=$(pwd)

FILE_PREFIX=all-mysql-
BACKUP_DIR=/opt/backup/mysql/dumps
ARCHIVE_WINDOW_DAYS=30

cd $BACKUP_DIR

# Create YYYYMMDD datestamp for Today - $ARCHIVE_WINDOW_DAYS
ARCHIVE_WINDOW_IN_SECS=$(echo "$(date +%s) - (${ARCHIVE_WINDOW_DAYS} * 86400)" | bc)
PURGE_BEFORE_DATE=$(date -d @${ARCHIVE_WINDOW_IN_SECS} +%Y%m%d)

for backup_file in $FILE_PREFIX*
do
    # Trim prefix, time portion of date stamp, and file extension
    # from $backup_file to allow numeric comparison against YYYYMMDD
    backup_trim_tmp=${backup_file#${FILE_PREFIX}}
    backup_trimmed=${backup_trim_tmp%-****.dump}

    if [ ${PURGE_BEFORE_DATE} -gt ${backup_trimmed} ]
    then
        rm $backup_file
    fi
done

cd $STARTING_DIR

3
私には完全に適切に見えますが、実際に行った方法よりも簡単な日付変換の方法を私は見ることができません。:)
ティンク

@tink-ありがとう。これには1つのライナーソリューションがあったと思わずにはいられません。私は、BASHlandよりもJavaLandに住む他のメンテナーにもっと関心を持っていました。おそらく唯一の懸念は、「2038年問題」である:)
TP

2
logrotateよりクリーンなソリューションではありませんか?
ott-- 2013年

2
このようなものについては、安全策も必要です(何らかの理由で新しいバックアップがない場合は、古いバックアップを削除しないでください)。
frostschutz 2013年

@ott-ユーザーランドでうまく機能する場合、これはオプションになる可能性があります。残念ながら、私たち(アプリエンジニア)はroot権限もsu権限も許可されていないため、syslogに出力したり、他のスーパーユーザー特権を必要とする場合、私たちは暗闇の中にいます。それは残念なことですが、それは現在の方針です:(
TP

回答:


3

最後の30ファイルを除くすべてを削除する別の方法:

rm $(ls -r | tail -n +31)

または、元の投稿のスクリプトの短いバージョンを次に示します。

cd /opt/backup/mysql/dumps
d=$(date -r $(($(date +%s)-30*86400)) +%Y%m%d)
for f in all-mysql-*; do
    [[ ${f#all-mysql-} < $d ]] && rm $f
done

オプション1では、30個を超えるファイルが発生する可能性がある中間バックアップは考慮されませんが、オプション2は私が達成したいと思っていたものです(より簡潔なスクリプト)。ただし、ポストされたスクリプトリファクタリングはエラーを生成したため、日付の割り当て行をd = $(date -d @ $(($(date +%s)-30 * 86400))+%Y%m%dに変更しました)、それは元の投稿のスクリプトと同じように機能しました。
TP

date -dはOS Xでは機能しませんでしたが、-rもgnu日付では別の意味を持つようです。
Lri

うん。別のGNU vs BSDの落とし穴:)
TP

1

最後の30ファイルを除くすべてを削除したい場合:

rm `echo " " all-mysql-*.dump | sed -r -e 's/( [^ ]+){0,30}$//'`

1日に1つのバックアップがあり、命名体系がそのままの状態である場合(つまり、アルファベット順=時系列順、ファイル名にスペースがない場合)は、これで要件を満たします。

コメントの1つに具体的にワンライナーを要求しました。個人的にはもっと書きたいです。この1つのライナーは少し危険です(sedが失敗すると、すべてが削除されます)。


現在、QAおよびローカル環境を更新するために、1日に複数のバックアップ(ダンプ)が存在する可能性があります。多分それを綴り、安全にプレーすることが最善のアプローチです。
TP

その場合、最大40または50のファイルを作成できます(ただし、ストレージスペースを確保できる数は多くなります)。これらのバックアップ用に個別のファイルシステムがある場合は、空き容量を統計し、十分な空き容量がない場合は最初のバックアップのみをrmすることもできます。
frostschutz 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.