1

Я использую следующую функцию, чтобы найти большие файлы (> 40MBytes) для различных пользователей Linux в моей команде. Возможно, что некоторые из них могут не иметь файлов размером более 40 МБ. Вывод $DUMPFILE каждому пользователю в crontab по электронной почте. Есть ли интеллектуальный способ обнаружить, что $DUMPFILE не имеет списка файлов и, следовательно, нет смысла отправлять электронное письмо этому пользователю?

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

}

1 ответ1

0

Я бы сделал так, чтобы возвращаемое значение функции зависело от результата команды 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

Итак, в вашем скрипте вы вызовете функцию и затем отправите только почту (это то, что делает && ), если она завершается корректно, то есть возвращает значение 0. Я также удалил команды cd так как они не делали ничего полезного. Вам не нужно cd в каталог для поиска через него.

По моему мнению, было бы лучше создать DUMPFILE, только если найдены большие файлы, но я не знаю, что именно вы пытаетесь сделать, поэтому я оставил это без изменений. Вы могли бы сделать все это намного чище с чем-то вроде:

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;

Таким образом, вы избегаете создания ненужных файлов.

Если команда sendmail выполняется из cron а не из вашего скрипта (что кажется странным), вы можете создать временный файл с результатом команды find и затем запросить файл из cron . Сохраните все, как я предложил выше, и:

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 `

Тогда из cron:

@daily your_bash_script.sh; grep YES /tmp/find_result && sendmail

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .