归档日志的Bash脚本

时间:2018-09-16 08:14:33

标签: bash

需要bash脚本专家的协助来创建脚本。

我的要求- 需要在源位置(以下提到的位置)中查找超过3天的所有日志,然后将所有日志移动到另一个位置并按以下示例中的.zip文件进行存档。还计划每天晚上作为cron工作运行此脚本。

示例日志源位置- / tmp / logs / source / 2018/09/15 / server1_logs

归档的zip文件之后在目标位置应为这样- /tmp/logs/destination/2018_09_15.zip

#!/bin/bash

LOG_SOURCE="/tmp/logs/source"                               
LOG_DESTINATION="/tmp/logs/destination"                                 
ARCHIVE_AFTER="3"

archiveDay=$(date "+%d" -d "$ARCHIVE_AFTER days ago")
archiveMonth=$(date "+%m" -d "$ARCHIVE_AFTER days ago")
archiveYear=$(date "+%Y" -d "$ARCHIVE_AFTER days ago")
logArchiveSrcDirectory=$LOG_SOURCE"/"$archiveYear"/"$archiveMonth"/"$archiveDay
logArchiveDstZipFile=$LOG_DESTINATION"/"$archiveYear"_"$archiveMonth"_"$archiveDay".zip"
echo $logArchiveSrcDirectory
echo $logArchiveDstZipFile

# Log Archive Process
zip -r  $logArchiveDstZipFile $logArchiveSrcDirectory

# Delete original log directory if archiving successfull 
if [ -f "$logArchiveDstZipFile" ] 
    then
    rm -r $logArchiveSrcDirectory
fi

此脚本有效,但仅移动并压缩了前三天的那一天,但其他旧目录仍然存在。

2 个答案:

答案 0 :(得分:1)

我们可以连接bash的许多命令和功能来开发解决方案。这是我的版本:

#!/bin/bash

LOG_SOURCE="/tmp/logs/source"                               
LOG_DESTINATION="/tmp/logs/destination"                                 
ARCHIVE_AFTER="3"

# That directory probably exists already but let us say it doesn't
mkdir -p "$LOG_DESTINATION"

find "$LOG_SOURCE" -type d -regextype gnu-awk -regex "$LOG_SOURCE/[[:digit:]]{4}/[[:digit:]]{2}/[[:digit:]]{2}" \
    | sed -r -n 's#^.*([0-9]{4})/([0-1][0-9])/([0-3][0-9])$#\1 \2 \3#p' \
    | while read Y M D; do
        if [[ "$Y$M$D" < $(date "+%Y%m%d" -d "$ARCHIVE_AFTER days ago") ]]
        then
            logArchiveSrcDirectory="$LOG_SOURCE/$Y/$M/$D"
            logArchiveDstZipFile="$LOG_DESTINATION/"$Y"_"$M"_"$D".zip"

            echo $logArchiveSrcDirectory
            echo $logArchiveDstZipFile

            if zip -r  "$logArchiveDstZipFile" "$logArchiveSrcDirectory"
            then
                rm -r "$logArchiveSrcDirectory"
            fi

        fi
    done 

让我们检查一下我做了什么:

  • find将打印符合我们条件的文件:
    • "$LOG_SOURCE":这是搜索将开始的目录。它将从该目录递归搜索
    • -type d:我们只在寻找目录
    • -regextype gnu-awk:下一个正则表达式选项将使用GNU awk的方言
    • -regex "$LOG_SOURCE/[[:digit:]]{4}/[[:digit:]]{2}/[[:digit:]]{2}":我们正在寻找以下路径,该路径以源目录开头,后跟四,2和2位数字,并用斜杠分隔。
  • 我们将从find中获取输出并进行连接,因此sed。我们使用sed来变换find中的每一行
    • -r:我们将在此步骤中使用扩展的正则表达式
    • -n:我们不想显示与搜索内容不匹配的行
    • 's#^.*([0-9]{4})/([0-1][0-9])/([0-3][0-9])$#\1 \2 \3#p':我们从每一行中分离出Year,Month和Day组成部分。我们用空格分隔每个元素
  • 我们使用while read Y M D; do读取sed输出的每一行,并分别设置变量$Y$M$D
    • if [[ "$Y$M$D" < $(date "+%Y%m%d" -d "$ARCHIVE_AFTER days ago") ]]:我们以类似的格式在字典上比较了当前正在处理的日期和3天前date的输出。如果该日期较早(比以前早),我们会做一些thinsgs:
      • 我们设置源目录和目标目录的名称
      • if zip -r "$logArchiveDstZipFile" "$logArchiveSrcDirectory":我们检查zip命令是否正确运行
      • rm -r "$logArchiveSrcDirectory":如果一切正常,我们将删除目录

我有点累,所以我不知道是否有错误。但这似乎对我有利。那是你要找的东西

答案 1 :(得分:0)

这就是为什么:

logArchiveSrcDirectory=$LOG_SOURCE"/"$archiveYear"/"$archiveMonth"/"$archiveDay

您使用$archiveDay来定义来源。今天的$archiveDay13

所以您说要压缩以执行此操作:

zip -r /tmp/logs/destination/2018_09_132.zip /tmp/logs/source/2018/09/13

因此,它将仅压缩.../13目录中的文件。

现在,如果要查找所有3天以上的文件,可以使用:

find <SOURCE DIRECTORY> -type f -mtime +3 -print

请注意,这也会在所有子目录中递归查找文件。