Script para apagar arquivos antigos (tar) em um diretório se o número exceder 15?

1

Por favor, qualquer pessoa pode dar a solução para isso Estou tentando fazer o backup do gitlab para outro servidor, o script deve excluir os arquivos antigos se o número do arquivo no diretório exceder 15?

    
por harsha 24.02.2017 / 08:54

2 respostas

2

Diclaimer: Eu testei os seguintes comandos com nomes de arquivos que contêm espaços, mas não com nomes de arquivos que contêm novas linhas. Eu suspeito que eles não vão jogar muito bem com nomes de arquivos contendo o caractere de nova linha, e evitaria usá-los se você suspeitar que nomes de arquivos que os contenham possam ser criados.

Essa abordagem depende do ctime do arquivo, portanto, se os arquivos tiverem seus atributos alterados, eles parecerão mais recentes do que o tempo de criação. Só você pode decidir se confiar em ctime é aplicável em sua situação. Se você preferir usar o mtime, altere -printf "%C+ %p\n" para -printf "%T+ %p\n" nos comandos find .

O seguinte comando pode ser emitido dentro do diretório que contém seus arquivos tar. Isso pressupõe que os nomes dos arquivos sejam todos algo como something.tar . Se os nomes dos arquivos não forem desse formato, o comando precisará ser modificado, alterando o -iname '*.tar.' para -iname '*.tar.gz*' se os arquivos forem arquivos .tar.gz ou removendo toda a string -iname '*.tar.' se você quiser para operar em qualquer arquivo desse diretório, independentemente do formato do nome do arquivo.

find . -mindepth 1 -maxdepth 1 -type f -iname '*.tar' -printf "%C+ %p\n" | sort -n | cut -d ' ' -f 2- | head -n -15 | xargs -I{} echo "{}"

Se isso mostrar os arquivos mais antigos, fora do limite de 15 arquivos, use o seguinte comando para excluir esses arquivos.

find . -mindepth 1 -maxdepth 1 -type f -iname '*.tar' -printf "%C+ %p\n" | sort -n | cut -d ' ' -f 2- | head -n -15 | xargs -I{} rm "{}"

Por meio de explicação:

  • find . -mindepth 1 -maxdepth 1 -type f -iname '*.tar' -printf "%C+ %p\n" listará todos os arquivos que terminam em .tar em . (o diretório atual) sem recursão em subdiretórios. Em seguida, ele imprime o timastamp ctime seguido por um espaço e o nome do arquivo com um caractere de nova linha à direita.
  • | sort -n classifica a saída de find numericamente, portanto, os arquivos são listados do mais antigo para o mais recente (por ctime).
  • | cut -d ' ' -f 2- remove o registro de data e hora adicionado que find criou, mas preserva a ordem dos arquivos listados por sort .
  • | head -n -15 apara os 15 itens inferiores da saída de cut .
  • xargs -I{} rm "{}" executa o comando rm em cada arquivo, garantindo que o nome do arquivo não seja dividido em espaço em branco.

Isso pode ser escrito como um script bash, com o número de arquivos a serem retidos e o diretório no qual operar como variáveis no script. É possível passar o diretório e a contagem de retenção de arquivos como argumentos, mas não vou cobrir isso aqui.

#!/bin/bash

file_limit=15
dir=/directory/containing/tarfiles

find "$dir" -mindepth 1 -maxdepth 1 -type f -iname '*.tar' -printf "%C+ %p\n" | sort -n | cut -d ' ' -f 2- | head -n -"$file_limit" | xargs -I{} rm "{}"

Se você salvar este script em algum lugar, por exemplo /home/user/trim_old_gits e garanta que você concedeu permissões executáveis. O script pode ser executado a partir da linha de comando, digitando:

/home/user/trim_old_gits

Ou de dentro de /home/user :

./trim_old_gits

Como mencionado em Jacob é maravilhoso python answer , usando o utilitário cron seria uma boa maneira de garantir que isso ocorra regularmente, se não for crucial que os arquivos sejam excluídos imediatamente, ou inotifywait se o timing é mais sensível.

    
por Arronical 24.02.2017 / 13:07
1

Dado o fato de que ctime e mtime não são garantia de que você realmente exclua os arquivos mais antigos , dependendo do que aconteceu com os arquivos intermediários, o script abaixo exclui os arquivos, excedendo um número arbitrário, dentro de um determinado diretório.

(ao) aqui podemos ler:

% bl0ck_qu0te%

Tendo dito isso

De acordo com o ctime de um arquivo, o pequeno script de segundo plano abaixo excluirá os arquivos mais antigos se o número de arquivos exceder um número definido. É seu decidir se essa é uma opção utilizável na sua situação.

O script

#!/usr/bin/env python3
import sys
import os
from operator import itemgetter
import time

dr = sys.argv[1]; n = int(sys.argv[2])

while True:
    time.sleep(3)
    # list files; get the number of files
    files = [os.path.join(dr, f) for f in os.listdir(dr)]; nfiles = len(files)
    if nfiles > n:
        # if nfiles exceeds the threshold, get the number of files to delete
        todel = nfiles - n
        # sort the list by creation date, delete the oldest
        del_list = sorted([
            [f, os.path.getctime(f)] for f in files
            ], key=itemgetter(1))[:todel]
        for f in del_list:
            os.remove(f[0])

Como usar

  1. Copie o script em um arquivo vazio, salve-o como keep_latest.py
  2. Teste- execute o script a partir de um terminal com o caminho para o diretório e o número de arquivos (mais recentes) para manter os argumentos:

    python3 '/path/to/keep_latest.py' '/path/to/directory' 15
    

    para manter os últimos 15 arquivos em '/path/to/directory'

  3. Se tudo funcionar bem, adicione a Startup Applications: Dash > Aplicativos de inicialização > Adicionar. Adicione o comando:

    python3 '/path/to/keep_latest.py' '/path/to/directory' 15
    

Outras opções

O script acima é uma das muitas opções. Se mtime ou ctime bastasse, outra opção seria usar inotifywait , e faça o mesmo que o script acima, mas somente se um arquivo for adicionado, movido ou copiado para o diretório.

Se a precisão de tempo (remoção imediata de arquivos extras) não for realmente importante, também um comando executado por cron seria uma boa opção.

Se o loop de inotifywait ou o script acima fosse mais eficiente, seria objeto de teste e comparação.

De qualquer maneira, os recursos usados seriam praticamente nenhum.

    
por Jacob Vlijm 24.02.2017 / 11:20