CentOS 7サーバーで自動バックアップを実行するスクリプトを作成しました。バックアップは/home/backupディレクトリに保存されます。スクリプトは機能しますが、今度はバックアップが発生した後にファイルの数を数え、数字が5を超える場合は、最も古いバックアップを削除する方法を望んでいます。
以下は私のバックアップスクリプトです。
#!/bin/bash
#mysqldump variables
FILE=/home/backup/databasebk_!`date +"Y-%m-%d_%H:%M"`.sql
DATABASE=database
USER=root
PASS=my password
#backup command process
mysqldump --opt --user=${USER} --password=${PASS} ${DATABASE} > ${FILE}
#zipping the backup file
gzip $FILE
#send message to the user with the results
echo "${FILE}.gz was created:"
ls -l ${FILE}.gz
# This is where I would like to count the number of files
# in the directory and if there are more than 5 I would like
# to delete the oldest file. Any help is greatly appreciated
ありがとう - マイク
答え1
ループのない純粋なBashでは:
ls -t | tail -n +6 | xargs -d '\n' rm
説明する:
ls -t
現在のディレクトリ内のすべてのファイルを変更時間で並べ替え、最新のファイルから印刷します。tail -n +6
最初の5行を無視し、6行目から行を印刷します。xargs -d '\n' rm
渡されたファイルを1行に1つずつ削除します。ファイル名にスペースや引用符がないと確信している場合はxargs rm
。
これにより、ディレクトリに5つのファイルしか残らないように、必要な数のファイルが削除されます。最も古いファイルを1つだけ+6
削除するには1
。
答え2
見て5より大きい場合は、ファイルを削除できset -- /home/backup/databasebk_*
ます$#
。
したがって、コードは次のように見えます。
set -- /home/backup/databasebk_*
while [ $# -gt 5 ]
do
echo "Removing old backup $1"
rm "$1"
shift
done
これは、選択したファイル名が「古いものから」自動的にソートされるために機能します。
一貫性のために変数を設定します。 (普通はこう呼んでいますが、好きなBASE
ように歌ってもいいです。)
だから
BASE=/home/backup/databasebk_
FILE=${BASE}!`date +"%Y-%m-%d_%H:%M"`.sql
....
set -- ${BASE}*
while [ $# -gt 5 ]
do
echo "Removing old backup $1"
rm "$1"
shift
done
答え3
私の考えのより良いアプローチは、ログロテートを使用することです。これは、アプリケーションがスクリプトを使用して達成したいことをすでに実行しているためです。テストサーバーで次のスクリプトをテストしました。
- データベースを手動でバックアップします。ファイルが存在しない場合はlogrotateが実行されないため、これが必要です。
$ mysqldump -uroot -pmy5trongpass database > mydatabase.sql
$ ls
$ mydatabase.sql
最初のデータベースが作成されていない場合のエラーの例です。
#**logrotate -f** will force our new rule to run now and backup the database
#this is for testing purposes.
$ logrotate -f /etc/logrotate.d/mysql_backup
error: stat of /home/backups/mydatabase.sql failed: No such file or directory
- logrotate ファイル/ルールを作成します。これは/etc/logrotate.d/にある他の規則に基づいて私が作成した規則です。
$ cat /etc/logrotate.d/mysql_backup
/home/backups/mydatabase.sql{
create 640 root mysql
daily
rotate 2
nocompress
postrotate
mysqldump -uroot -pmy5trongpass test > mydatabase.sql;
echo "done"
endscript
}
- 以下を使用して構成をテストします。
$ logrotate -f /etc/logrotate.d/mysql_backup
$ logrotate -f /etc/logrotate.d/mysql_backup
done
$ ll
total 16
-rw-r-----. 1 root mysql 1261 Feb 3 21:46 mydatabase.sql
-rw-r-----. 1 root mysql 1261 Feb 3 21:44 mydatabase.sql.1
-rw-r-----. 1 root mysql 1261 Feb 3 21:44 mydatabase.sql.2
次のオプションを使用して、日付を表示するように変更できる数値の後に新しいファイルが生成されることを確認できます。
https://linux.die.net/man/8/logrotate
dateext
Archive old versions of log files adding a daily extension like YYYYMMDD instead of simply adding a number. The extension may be configured using the dateformat option.
dateformat format_string
Specify the extension for dateext using the notation similar to strftime(3) function. Only %Y %m %d and %s specifiers are allowed. The default value is -%Y%m%d. Note that also the character separating log name from the extension is part of the dateformat string. The system clock must be set past Sep 9th 2001 for %s to work correctly. Note that the datestamps generated by this format must be lexically sortable (i.e., first the year, then the month then the day. e.g., 2001/12/01 is ok, but 01/12/2001 is not, since 01/11/2002 would sort lower while it is later). This is because when using the rotate option, logrotate sorts all rotated filenames to find out which logfiles are older and should be removed.
答え4
files=( /home/backup/* )
# files is now an array containing file names in the directory
oldest=""
if (( ${#files[@]} > 5 )) ## are there more than five?
then
for name in "${files[@]}" ## loop to find oldest
do
a=$( stat --printf=%Y "$name" )
if [ -z "$oldest" ] || (( a < age ))
then
age="$a"
oldest="$name"
fi
done
rm "$oldest"
fi
いくつかのコメント:
私は/home/backup/*
そのディレクトリ内のすべてのファイルを見つけることについて話しています/home/backup/databasebk_*.sql.gz
が、圧縮されたダンプだけを探していると言えます。
日付はYMDhm形式の順序なので、ファイルシステムに基づいて最も古いファイルを見つけるために「stat」を使用しています。ファイル名を比較できます。
if [ -z "$oldest" ] || [ "$name" -lt "$oldest" ]
/home/backup/ にサブディレクトリがある場合、このスクリプトは中断されます。