Estrutura repetição [RESOLVIDO]

1. Estrutura repetição [RESOLVIDO]

Fernando Almeida
fernandoalsan

(usa CentOS)

Enviado em 07/11/2012 - 10:05h

Bom dia pessoal,

Sou novo no ambiente de geração de script e esse é meu primeiro script.
A estrutura tive ajuda do gerente da minha área, mas no momento está complicado solicitar ajuda, comprei o livro "Shell Scriot Professional" para aprender e ter um conhecimento mais profundo dessa área.

O problema que está ocorrendo é fazer o "for" verificar a data dos logs e somente remover os logs que após 5 dias passados, deixando 1 semana se log no servidor para caso for necessário realizar algum restore.

Estrutura script

ANO=$(date +%Y)
MES=$(date +%m)
DIA=$(date +%d)
DIAS_OLD=$(date --date "5 days ago")
GZIP="/usr/bin/gzip -rf"
bkporigem="/root/teste/log/$ANO/$MES"
bkpdestino="/root/teste/bkp_teste/$ANO/$MES/"

# Verifica destino
if [ -d $bkpdestino ]
then
echo "-> Diretorio $bkpdestino existe"

else
echo "-> Criando diretorio $bkpdestino"
mkdir -p $bkpdestino
fi
********************** DESSE MOMENTO PARA BAIXO ESTÁ GERANDO O PROBLEMA **************
# Zipando e Movendo arquivos
for logzip in $(ls $bkporigem |grep -v "$DIAS_OLD")
do
echo "-> Processo de compressao do diretorio $logzip"
# $GZIP $bkporigem/$logzip
echo "-> Movendo arquivos de $logzip"
mv $bkporigem/$logzip $bkpdestino

done

echo "-> Fim Script"


Caso alguém puder me ajudar e auxiliar uma melhora nesse caso agradeço.

Abraços

Fernando Almeida



  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 07/11/2012 - 19:55h

Nada disso é necessário. O que se quer pode ser feito somente com o comando find, por meio da diretiva de teste -mtime (ou -mmin).

E, senhores, construções do tipo

for arq in /algum_diretorio/*; do
faz_alguma_coisa_com "$arq"
done


ou (o que é pior ainda, porque redundante e mais dispendioso)

for arq in `ls /algum_diretorio/*`; do
faz_alguma_coisa_com "$arq"
done


são potencialmente NOCIVAS, pois aquele asterisco pode expandir para uma quantidade muito grande de entradas, gerando uma linha de comando longa demais para ser aceita pelo shell Além disso, é teoricamente possível que os nomes dos arquivos contenham espaços (e até mesmo quebras de linhas), que podem ser confundidos se sua expansão não for feita com cuidado. Por isso, melhor é fazer, de novo, com find, em uma das seguintes formas.

# CASO 1: Se o "faz_alguma_coisa_com" for um simples comando
# e puder ser aplicado a vários arquivos ao mesmo tempo.

find /algum_diretorio -maxdepth 1 -mindepth 1 -print0 | xargs -0 comando


# CASO 2: Se o "faz_alguma_coisa_com" for um simples comando
# mas tiver de ser aplicado a um arquivo de cada vez.

find /algum_diretorio -maxdepth 1 -mindepth 1 -exec comando "{}" ";"


# CASO 3: Se o "faz_alguma_coisa_com" for uma sequencia de comandos,
# pode-se fazer um script com esses comandos e chamar tal script, como
# se fosse um dos casos acima, ou embutir os multiplos comandos num comando
# so, via shell, como mostrado abaixo (como se fosse uma chamada a função
# system() do C).

find /algum_diretorio -maxdepth 1 -mindepth 1 -print0 | xargs -0 \
sh -c 'for a in "$@"; do b="`echo \"$a\" | tr \[a-z\] \[A-Z\]`"; echo "$a --> $b"; done'


Nos exemplos acima, eu supus o find (e seu parceiro xargs) da GNU. Outros sistemas, como Solaris ou AIX, têm um find que não dispõe de muitas das operações da versão da GNU, incluindo -print0, -mindepth e -maxdepth, usados nos exemplos.

A ausência mais grave é a de -print0, o que impede tratar arquivos que contenham quebras de linha no nome. Felizmente, tais arquivos são raros. Mas os operadores disponíveis em versões menos elaboradas do find ainda permitem conseguir efeitos como os mostrados acima, mas exigem expressões mais elaboradas. Mesmo assim, é bom levar em consideração essas diferenças de versões em scripts que tenham de rodar em diferentes sistemas (ou versões de um mesmo sistema). Assim sendo, o find mostrado no exemplo do "CASO 1", acima, teria de ser reescrito numa forma parecida com a que se segue.

find /algum_diretorio \( -name etc -o \( -type d -print -prune \) \) -o -print | xargs comando 


3. Re: Estrutura repetição [RESOLVIDO]

Lucas Doná Sfalcin
lucasdona

(usa Linux Mint)

Enviado em 07/11/2012 - 12:02h

Vc não teria que verificar a data do arquivo.log e comparar se já tem 5 dias para compactar e copiar?
Para vefiricar a data de criação do arquivo.log vc pode fazer:
Aqui vc pega a data completa de criação do arquivo.log
ls -lh arquivo.log | awk '{print $6}' 

Aqui vc pega o ano de criação
ls -lh arquivo.log | awk '{print $6}' | cut -c1-4 

Aqui vc pega o mes de criação
ls -lh arquivo.log | awk '{print $6}' | cut -c6-7 

Aqui vc pega o dia de criação
ls -lh arquivo.log | awk '{print $6}' | cut -c9-10 


A partir daí vc só tem que jogar esse dia em uma variável:
DIA_CRIACAO_LOG=$(ls -lh arquivo.log | awk '{print $6}' | cut -c9-10) 

e fazer as comparações> Vamos supor que o dia de criação foi 05 e hoje é 11, então:
CONT_DIAS=$(($DIA_ATUAL - $DIA_CRIACAO_LOG))
if [ $CONT_DIAS -ge 5 ]
then
# entrou no if, pois, DIA_ATUAL=11 e DIA_CRIACAO_LOG=5, CONT_DIAS=6, 6 >= 5
else
echo "aguardando nova verificação"
sleep 60
fi


Só tem que tomar cuidado, quando virar o mês, daí tem que tratar isso. Então vc pode até colocar isso nun while infinito e deixar rodando e fazer a verificação de tempo em tempo ou mesmo colocá-lo no crontab.

Não sei se é isso que vc estava precisando, mas fica aí a dica. :-)


4. Re: Estrutura repetição [RESOLVIDO]

Fernando Almeida
fernandoalsan

(usa CentOS)

Enviado em 07/11/2012 - 12:15h

lucasdona escreveu:

Vc não teria que verificar a data do arquivo.log e comparar se já tem 5 dias para compactar e copiar?
Para vefiricar a data de criação do arquivo.log vc pode fazer:
Aqui vc pega a data completa de criação do arquivo.log
ls -lh arquivo.log | awk '{print $6}' 

Aqui vc pega o ano de criação
ls -lh arquivo.log | awk '{print $6}' | cut -c1-4 

Aqui vc pega o mes de criação
ls -lh arquivo.log | awk '{print $6}' | cut -c6-7 

Aqui vc pega o dia de criação
ls -lh arquivo.log | awk '{print $6}' | cut -c9-10 


A partir daí vc só tem que jogar esse dia em uma variável:
DIA_CRIACAO_LOG=$(ls -lh arquivo.log | awk '{print $6}' | cut -c9-10) 

e fazer as comparações> Vamos supor que o dia de criação foi 05 e hoje é 11, então:
CONT_DIAS=$(($DIA_ATUAL - $DIA_CRIACAO_LOG))
if [ $CONT_DIAS -ge 5 ]
then
# entrou no if, pois, DIA_ATUAL=11 e DIA_CRIACAO_LOG=5, CONT_DIAS=6, 6 >= 5
else
echo "aguardando nova verificação"
sleep 60
fi


Só tem que tomar cuidado, quando virar o mês, daí tem que tratar isso. Então vc pode até colocar isso nun while infinito e deixar rodando e fazer a verificação de tempo em tempo ou mesmo colocá-lo no crontab.

Não sei se é isso que vc estava precisando, mas fica aí a dica. :-)



Lucas, obrigado pela resposta, mas surgiu uma dúvida com essa estrutura, posso colocar o caminho absoluto aonde está os arquivos?

Nessa repetição para contar os dias, abaixo do "then" posso encaixar a estrutura para zipar as pastas que entrem na condição e após mover essas pastas ?

Abraço.


5. Re: Estrutura repetição [RESOLVIDO]

Lucas Doná Sfalcin
lucasdona

(usa Linux Mint)

Enviado em 07/11/2012 - 12:46h

Tá dizendo se pode ser assim:

ANO=$(date +%Y)
MES=$(date +%m)
DIA=$(date +%d)
DIAS_OLD=$(date --date "5 days ago")
GZIP="/usr/bin/gzip -rf"
bkporigem="/root/teste/log/$ANO/$MES"
bkpdestino="/root/teste/bkp_teste/$ANO/$MES/"

# Verifica destino
if [ -d $bkpdestino ]
then
echo "-> Diretorio $bkpdestino existe"
else
echo "-> Criando diretorio $bkpdestino"
mkdir -p $bkpdestino
fi
CONT_DIAS=$(($DIA_ATUAL - $DIA_CRIACAO_LOG))
if [ $CONT_DIAS -ge 5 ]
then
echo "-> Processo de compressao do diretorio $logzip"
$GZIP $bkporigem/$logzip
echo "-> Movendo arquivos de $logzip"
mv $bkporigem/$logzip $bkpdestino
else
echo "aguardando nova verificação"
sleep 60
fi


Pode sim, sem problemas, mas no caso aí $logzip não foi definido em momento algum e relembrando, tem que tratar a virada do mês, por exemplo, data do log é dia 27 daí vai virar o mês e não vai dar a diferença de 5 dias nunca, então, tem que fazer alguma verificação parecida com, se DIA_ATUAL for menor que DIA_CRIACAO_LOG é prq o mês virou, então, vc teria que fazer (ULTIMO_DIA_MES_ATUAL - DATA_CRIACAO_LOG + DIA_ATUAL) aí vc teria a conta certa, exemplo: data criação do log é 29, virou o mês, dia atual é 2, então se passaram 4 dias, então é, 31 - 29 + 2 = 4, acho que assim resolve o problema de virar o mês, mas mesmo assim tem os meses que vão até 30 e 31, hehehe, complica um pouco mais, mas o interessante é vc quebrar a cabeça pra poder pegar o rítmo. :-), qualquer dúvida estamos aí pra ajudar, abraços.


6. Re: Estrutura repetição [RESOLVIDO]

Fernando Almeida
fernandoalsan

(usa CentOS)

Enviado em 07/11/2012 - 13:04h

lucasdona escreveu:

Tá dizendo se pode ser assim:

ANO=$(date +%Y)
MES=$(date +%m)
DIA=$(date +%d)
DIAS_OLD=$(date --date "5 days ago")
GZIP="/usr/bin/gzip -rf"
bkporigem="/root/teste/log/$ANO/$MES"
bkpdestino="/root/teste/bkp_teste/$ANO/$MES/"

# Verifica destino
if [ -d $bkpdestino ]
then
echo "-> Diretorio $bkpdestino existe"
else
echo "-> Criando diretorio $bkpdestino"
mkdir -p $bkpdestino
fi
CONT_DIAS=$(($DIA_ATUAL - $DIA_CRIACAO_LOG))
if [ $CONT_DIAS -ge 5 ]
then
echo "-> Processo de compressao do diretorio $logzip"
$GZIP $bkporigem/$logzip
echo "-> Movendo arquivos de $logzip"
mv $bkporigem/$logzip $bkpdestino
else
echo "aguardando nova verificação"
sleep 60
fi


Pode sim, sem problemas, mas no caso aí $logzip não foi definido em momento algum e relembrando, tem que tratar a virada do mês, por exemplo, data do log é dia 27 daí vai virar o mês e não vai dar a diferença de 5 dias nunca, então, tem que fazer alguma verificação parecida com, se DIA_ATUAL for menor que DIA_CRIACAO_LOG é prq o mês virou, então, vc teria que fazer (ULTIMO_DIA_MES_ATUAL - DATA_CRIACAO_LOG + DIA_ATUAL) aí vc teria a conta certa, exemplo: data criação do log é 29, virou o mês, dia atual é 2, então se passaram 4 dias, então é, 31 - 29 + 2 = 4, acho que assim resolve o problema de virar o mês, mas mesmo assim tem os meses que vão até 30 e 31, hehehe, complica um pouco mais, mas o interessante é vc quebrar a cabeça pra poder pegar o rítmo. :-), qualquer dúvida estamos aí pra ajudar, abraços.



Muito obrigado pela ajuda, mas não funcionou, estou fazendo testes e ver o que está apresentando problema.

ANO=$(date +%Y)
MES=$(date +%m)
DIA=$(date +%d)
DIAS_OLD=$(date --date "5 days ago")
GZIP="/usr/bin/gzip -rf"
bkporigem="/root/teste/log/$ANO/$MES"
bkpdestino="/root/teste/bkp_teste/$ANO/$MES/"

ls -lh $bkporigem | awk '{print $6}'
ls -lh $bkporigem | awk '{print $6}' | cut -c1-4
ls -lh $bkporigem | awk '{print $6}' | cut -c6-7
ls -lh $bkporigem | awk '{print $6}' | cut -c9-10
DIA_CRIACAO_LOG=$(ls -lh $bkporigem | awk '{print $6}' | cut -c9-10)

# Verifica destino
if [ -d $bkpdestino ]
then
echo "-> Diretorio $bkpdestino existe"
else
echo "-> Criando diretorio $bkpdestino"
mkdir -p $bkpdestino
fi

# Estrutura de Contagem e Processos ZIP e Mover
CONT_DIAS=$(($DIA-$DIA_CRIACAO_LOG))
if [ $CONT_DIAS -ge 5 ]
then
echo "-> Processo de compressao do diretorio $bkporigem"
$GZIP $bkporigem/
echo "-> Movendo arquivos de bkporigem"
mv $bkporigem/ $bkpdestino/
else
echo "aguardando nova verificacao"
fi

echo "-> Fim Script"

Abraços.



7. Re: Estrutura repetição [RESOLVIDO]

André Canhadas
andrecanhadas

(usa Debian)

Enviado em 07/11/2012 - 20:41h

Bom este é o melhor guia que já vi apesar de estar em inglês tem muitos exemplos uteis:
http://tldp.org/LDP/abs/abs-guide.pdf

De uma olhada na resposta numero 6:
http://tinyurl.com/c4xu7ox

Acho que é mais ou menos isso que precisa.


8. Re: Estrutura repetição [RESOLVIDO]

Fernando Almeida
fernandoalsan

(usa CentOS)

Enviado em 08/11/2012 - 10:51h

andrecanhadas escreveu:

Bom este é o melhor guia que já vi apesar de estar em inglês tem muitos exemplos uteis:
http://tldp.org/LDP/abs/abs-guide.pdf

De uma olhada na resposta numero 6:
http://tinyurl.com/c4xu7ox

Acho que é mais ou menos isso que precisa.


Muito obrigado, vou estudar e ver a melhor opção, utilizando o "find" trouxe um melhor resultado e deu mais segurança.






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts