如何在 crontab 中有条件地发送电子邮件

如何在 crontab 中有条件地发送电子邮件

我正在使用以下函数为团队中的各种 Linux 用户查找大文件(> 40MB)。其中一些用户可能没有大于 40MB 的文件。 的输出$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

我这样做的方法是让函数返回值取决于命令的结果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

因此,在您的脚本中,您将调用该函数,然后发送邮件仅有的(这就是所做的&&)如果它正确退出,ie 将返回值 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

相关内容