일부 의견:

일부 의견:

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전달된 파일을 한 줄에 하나씩 삭제합니다. 파일 이름에 공백이나 따옴표가 없다고 확신하는 경우에는 xargs rm.

이렇게 하면 디렉터리에 5개의 파일만 남도록 필요한 만큼의 파일이 삭제됩니다. 가장 오래된 파일 하나만 +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를 사용하는 것입니다. 해당 응용 프로그램이 스크립트를 사용하여 달성하려는 작업을 이미 수행하고 있기 때문입니다. 테스트 서버에서 다음 스크립트를 테스트했습니다.

  1. 데이터베이스를 수동으로 백업하십시오. 파일이 없으면 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
  1. 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
    }
  1. 다음을 사용하여 구성을 테스트하십시오.
$ 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/에 하위 디렉터리가 있으면 이 스크립트가 중단됩니다.

관련 정보