Como enviar um email condicionalmente no crontab

1

Estou usando a seguinte função para encontrar arquivos grandes (> 40MBytes) para vários usuários do Linux em minha equipe. É possível que alguns deles não tenham arquivos maiores que 40 MB. A saída de $DUMPFILE é enviada por e-mail para cada usuário no crontab. Existe uma maneira inteligente de detectar que o $DUMPFILE não possui a listagem de arquivos e, portanto, não faz sentido enviar um email para esse usuário?

function find_files_and_dirs {

    # $1 = base directory from where to start the search

    echo "***************************************************" >> $DUMPFILE
    echo "***************************************************" >> $DUMPFILE
    echo "List of large files for user $USER in $1" >> $DUMPFILE 
    echo "***************************************************" >> $DUMPFILE
    echo "***************************************************" >> $DUMPFILE

    cd $1

    find $1/ -user $USER -size +$LOWERSIZELIMIT -mtime +$MY_MTIME -type f \
      -printf "%s %p\n" 2> /dev/null | sort -nr | head -n $NUMFILES >> $DUMPFILE

    echo "***************************************************" >> $DUMPFILE
    echo "***************************************************" >> $DUMPFILE
    echo "Save states for user $USER in $1" >> $DUMPFILE 
    echo "***************************************************" >> $DUMPFILE
    echo "***************************************************" >> $DUMPFILE

    cd $1/shared_savestates

    find $1/shared_savestates -maxdepth 3 -user $USER -type d \
      -printf "%s %p\n" | sort -nr | head -n $NUMFILES >> $DUMPFILE

}
    
por user199889 17.02.2013 / 05:48

1 resposta

0

A maneira que eu faria isso é ter o valor de retorno da função dependente do resultado do comando find :

function find_files_and_dirs {

# $1 = base directory from where to start the search

echo "***************************************************" >> $DUMPFILE
echo "***************************************************" >> $DUMPFILE
echo "List of large files for user $USER in $1" >> $DUMPFILE 
echo "***************************************************" >> $DUMPFILE
echo "***************************************************" >> $DUMPFILE

status='find $1/ -user $USER -size +$LOWERSIZELIMIT -mtime +$MY_MTIME \ 
   -type f -printf "%s %p\n" 2> /dev/null | sort -nr | head -n $NUMFILES'
echo $status >> $DUMPFILE

echo "***************************************************" >> $DUMPFILE
echo "***************************************************" >> $DUMPFILE
echo "Save states for user $USER in $1" >> $DUMPFILE 
echo "***************************************************" >> $DUMPFILE
echo "***************************************************" >> $DUMPFILE


find $1/shared_savestates -maxdepth 3 -user $USER -type d -printf "%s %p\n" \
 | sort -nr | head -n $NUMFILES >> $DUMPFILE

## If the find command did not find anything
if [ -z "$status" ];
then
  return 1
else
  return 0
fi
}

find_files_and_dirs && sendmail_command

Assim, no seu script, você chamará a função e enviará o e-mail somente (é o que o && faz) se sair corretamente, ou seja, retornar um valor de 0. Eu também removeu os comandos cd , pois eles não estavam fazendo nada útil. Você não precisa cd em um diretório para pesquisá-lo.

Na minha opinião, seria melhor criar o DUMPFILE somente se arquivos grandes fossem encontrados, mas não sei exatamente o que você está tentando fazer, então deixei isso inalterado. Você pode ter tudo mais limpo com algo como:

function find_files_and_dirs {
## Save the lines you want to print into the variable
## $Lfiles for future use
read -d '' Lfiles <<"EOF"
***************************************************
***************************************************
    List of large files for user $USER in $1 
***************************************************
***************************************************
EOF

## Also save the shared_savestates lines
read -d '' Sstates <<"EOF"
***************************************************
***************************************************
    Save states for user $USER in $1
***************************************************
***************************************************
EOF

## Check for large files. This saves the output of the find 
## command into the variable $status
big_files='find $1/ -user $USER -size +$LOWERSIZELIMIT -mtime +$MY_MTIME -type f -printf "%s %p\n" 2> /dev/null | sort -nr | head -n $NUMFILES'
## Find the "shared_savestates" files
sfiles='find $1/shared_savestates -maxdepth 3 -user $USER -type d -printf "%s %p\n" | sort -nr | head -n $NUMFILES'


## If the find command did not find anything, i.e. if
## the variable $status is empty
if [ -z "$status" ];
then
    echo "$Lfiles" >> $DUMPFILE
    echo "No large files" >> $DUMPFILE
    echo "$Sstates" >> $DUMPFILE
    echo "$sfiles" >> $DUMPFILE
    ## Have the function return a value of 1
    return 1
 ## If the find command found big files 
 else
     echo "$Lfiles" >> $DUMPFILE
     echo "$big_files" >> $DUMPFILE
     echo "$Sstates" >> $DUMPFILE
     echo "$sfiles" >> $DUMPFILE
     ## Have the function return a value of 0, exit correctly
     return 0
 fi
}
## In bash "&&" means run the command on the left ONLY IF 
## the command on the left was successful. So, this line
## will run the send mail command ONLY IF large files were found.
find_files_and_dirs $1 && sendmail_command;

Dessa forma, você evita a criação de arquivos desnecessários.

Se o comando sendmail for feito de cron e não de dentro do seu script (o que parece meio estranho), você pode criar um arquivo temporário com o resultado do comando find e, em seguida, consultar o arquivo de% código%. Mantenha tudo como sugeri acima e:

echo "NO" > /tmp/find_result
status='find $1/ -user $USER -size +$LOWERSIZELIMIT -mtime +$MY_MTIME \ 
   -type f -printf "%s %p\n" 2> /dev/null && echo "YES" > /tmp/find_result | sort -nr | head -n $NUMFILES '

Então, do cron:

@daily your_bash_script.sh; grep YES /tmp/find_result && sendmail
    
por 17.02.2013 / 12:50

Tags