Problema referente ao diretório de trabalho em um loop de script de shell

1

Meu título é um pouco estranho eu sei. Eu não conseguia pensar em uma maneira de expressar melhor.

Eu tenho um diretório que contém vários diretórios, cada um cheio de arquivos de log. Todo arquivo de log é nomeado no formato AAAA-MM-DD.log. Por isso, seria /path/to/logs/tokyo/2017-06-29.log, /path/to/logs/london/2017-06-29.log, etc.

Um novo log é aberto todos os dias à meia noite com a nova data e os antigos nunca serão gravados novamente.

Existem literalmente milhares desses registros que remontam a anos e, embora sejam apenas arquivos de texto, eles estão começando a ocupar uma quantidade não desprezível de espaço. Então, o que eu estou tentando fazer é escrever um script que olhe em todos esses diretórios de log, encontre qualquer data antes de hoje e faça um bzip deles. Aqui está o que eu tenho até agora:

#!/bin/sh
LOGDATE=$(date +%Y-%m-%d)
LOGPATH="/path/to/logs"

for i in $(ls $LOGPATH/*/*.log); do
    if [ "$i" != "$LOGDATE.log" ];then
        tar cfjv $i.tar.bz2 $i
        rm $i
    else
    fi
done

Existem dois problemas que estou enfrentando. Primeiro, o $ (ls ...) no loop for equivale a dizer que a lista de argumentos é muito longa. Segundo, na declaração tar, eu quero que o arquivo de saída do bzip esteja no diretório onde o arquivo de log estava, mas ele parece deixá-los no diretório do qual o script está sendo executado, e não consigo encontrar uma maneira de faça o loop usar o diretório correto para cada arquivo correspondente que encontrar.

Presumivelmente, isso seria mais bem tratado com um comando find e xargs bem escrito, mas não consegui fazer um que faça o que eu preciso fazer.

O objetivo final deste script é encontrar todos os arquivos de log na estrutura de diretórios de log, verificar se não é o log de hoje, bzip-lo no lugar e excluir o log de texto. Ele seria executado uma vez imediatamente para cuidar de todos os logs antigos e, em seguida, adicionado ao crontab para ser executado logo após a meia-noite todos os dias.

O que preciso fazer para corrigir meu script? Ou existe melhor maneira?

A única restrição real é que é um servidor freebsd, então ele precisa usar sh ou csh, e usar ferramentas freebsd (significando, por exemplo, o achado do bsd ao invés do GNU find que possui opções mais extensas).

    
por Mella 29.06.2017 / 18:39

2 respostas

2

Isso poderia ser muito mais simples combinando find com o fato de que você não precisa fazer um tarball se estiver compactando apenas um arquivo:

find $LOGPATH/ -name \*.log -mtime 1 -execdir bzip2 "{}" \;

Se o find não tiver -mtime , você poderá falsificar usando touch para criar um arquivo (por exemplo, $DATEFILE ) com um horário específico da última modificação de, digamos, "meia-noite hoje" e, em seguida, use:

find $LOGPATH/ -name \*.log -not -newer /path/to/$DATEFILE -execdir bzip2 "{}" \;
rm /path/to/"$DATEFILE"
    
por 29.06.2017 / 18:45
0

Certamente, a maneira mais simples é utilizar a ferramenta que o FreeBSD já possui para isso - newsyslog .

Crie um arquivo /etc/newsyslog.conf ou edite o arquivo existente. Você dá o nome do arquivo (você pode usar curingas, embora você precise ter várias linhas para diretórios diferentes), quantas cópias de backup deseja manter (um grande número de casos no seu caso), quando passar o arquivo ( há um sinalizador para permitir que você mesmo faça isso), qual sistema de compressão você quer usar, etc.

Use newsyslog -FvC path-to-your-log-file para iniciá-lo pela primeira vez.

Aliás, você pode simplesmente colocar as linhas relevantes em /usr/local/etc/newsyslog.conf.d , em um arquivo com qualquer nome que desejar. Isso faz com que seja lembrado depois de atualizações um pouco mais fáceis.

    
por 09.07.2017 / 01:39