Maneira mais limpa de excluir arquivos no Linux, que incluem um carimbo de data como parte do nome do arquivo

8

Tenho um novo requisito para limpar os arquivos de despejo do MySQL com mais de 30 dias. Os arquivos usam uma convenção de nomenclatura "all-mysql-YYYYMMDD-HHMM.dump". Os arquivos estão localizados no sistema de arquivos montado na SAN, portanto, a restauração não é um problema, mas o espaço da unidade é limitado, infelizmente, e é preenchido rapidamente, exigindo intervenção humana frequente.

Exemplo de nomes de arquivos

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

Meu primeiro pensamento foi usar "find" dentro de um script em lote com -mtime +30; no entanto, os tempos de modificação não podem ser garantidos e alguns dos arquivos mais antigos podem evitar a data de eliminação :)

Criei o seguinte script BASH, mas esperava que houvesse uma maneira mais limpa de executar essa operação.

#!/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
TP
fonte
3
Parece perfeitamente adequado para mim e não vejo uma maneira mais simples de fazer a conversão de datas do que a maneira como você realmente tomou. :)
tink 27/03
@tink - Obrigado. Não posso deixar de pensar que havia uma solução única para isso. Eu estava mais preocupado com outros mantenedores que vivem mais no JavaLand do que no BASHland. Talvez a única preocupação é o problema "ano de 2038", então :)
TP
2
Não é logrotateuma solução mais limpa?
#
2
Para coisas como essas, também deve haver uma salvaguarda (não exclua backups antigos quando, por algum motivo, não houver novos).
27513 frostschutz
@ott - Isso pode ser uma opção se funcionar bem na terra do usuário. Infelizmente, nós (engenheiros de aplicativos) não são permitidos privilégios de root nem su, portanto, se algum tiver acesso ao syslog ou exigir outros privilégios de superusuário, estaremos no escuro. É uma chatice, mas é a política reinante :(
TP

Respostas:

3

Outra maneira de excluir todos, exceto os últimos 30 arquivos:

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

Ou aqui está uma versão mais curta do script na postagem original:

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
Lri
fonte
A opção 1 não levaria em consideração os backups intermediários que poderiam gerar mais de 30 arquivos, mas a opção 2 era o que eu esperava alcançar (um script mais conciso). No entanto, o refator de script publicado produziu um erro, então alterei a linha de atribuição da data para d = $ (data -d @ $ (($ (data +% s) -30 * 86400)) +% Y% m% d ) e funcionou de forma idêntica ao script na postagem original.
TP
date -d não funcionou no OS X, mas -r também parece ter um significado diferente na data do gnu.
Lri
Sim. Outra pegadinha GNU vs BSD :)
TP
1

Se você deseja excluir todos, exceto os últimos 30 arquivos:

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

Isso atenderia aos seus requisitos, desde que haja um backup por dia, e o esquema de nomenclatura permaneça como está (por exemplo, ordem alfabética = ordem cronológica, sem espaços nos nomes dos arquivos).

Você solicitou especificamente uma linha em um de seus comentários. Pessoalmente, gosto de escrever mais. Este liner está um pouco perigoso (se o sed falhar, tudo será excluído).

frostschutz
fonte
Atualmente, pode haver vários backups (despejos) por dia para atualizar o controle de qualidade e os ambientes locais. Talvez soletrar e jogar pelo seguro seja a melhor abordagem.
TP
Você pode configurá-lo para 40 ou 50 arquivos (no entanto, muitos podem ter espaço para armazenamento). Se você tivesse um sistema de arquivos separado para esses backups, poderia até especificar o espaço livre e liberar apenas o primeiro backup quando não houver espaço suficiente disponível.
27613 frostschutz