BASH脚本 - 测试年龄和压缩文件

时间:2011-12-07 16:54:51

标签: bash

首先是一些背景。我们有一个供应商应用程序,它生成日志和配置文件,并将它们存储在一组特定的文件夹中。然后,它会在预定的时间后对日志进行gzip。

我们定期使用该服务器上的脚本将这些文件夹同步到备份服务器(至少每天一次)。为了减少空间,我们运行另一个脚本来gzip任何未被修改30天的文件。这会导致问题,因为最终源服务器将运行其rsync并将* .gz文件发送到备份服务器。因为我们将拥有较旧的纯文本文件以及较新的GZ文件的副本,当我们的压缩脚本运行时,它会尝试覆盖.gz文件。这会造成竞争条件。

我正在使用以下代码片段来修复它。这是我的测试脚本。

#!/bin/bash

#Array of local directories
localDirs=("./testdir/")

#Loop through local directories
for i in "${localDirs[@]}"
        do
#Find non-gz files in current local dir
        for FILE in `ls --hide=*.gz $i`;
#If the file doesn't have a matching .gz file, compress it
                do if [ ! -f ${FILE}.gz ]
                        then
                        echo "$FILE: Gzip doesn't exist"
                        echo compressing $file
#test to make sure that the file is 30 days old, and if it is, gzip
                        #find $i$FILE -type f -mtime 30 -exec gzip {} \;
                fi
                done
        done
exit

这不起作用 - 它似乎仍然列出目录中的每个文件,无论它是否具有gzip对应项。关于代码的任何其他建议将不胜感激,我仍然是一个BASH新手。

编辑:

根据建议修改了代码(不知道反引号已被弃用!):

#!/bin/bash

#Array of local directories
localDirs=("./testdir/")

#Loop through local directories
for i in "${localDirs[@]}"
        do
#Test set FILE equal to non-gz files in current local dir
        for FILE in $(find $i ! -name "*.gz")
#If the file doesn't have a matching .gz file, compress it
                do if [ ! -f ${FILE}.gz ]
                        then
                        echo "$FILE: Gzip doesn't exist"
                        echo compressing $FILE
#test to make sure that the file is 30 days old, and if it is, gzip
                        find $FILE -type f -mtime 30 -exec gzip {} \;
                fi
                done
        done
exit

我创建了一个名为./testdir/oldfile.txt的文件,还有一个名为./testdir/oldfile.txt.gzip的文件。它仍然试图将./testdir/oldfile.txt压缩为./testdir/oldfile.txt.gzip。奇怪的是,如果我删除压缩文本,回声不会显示列出的旧文件,因为它有一个相应的.gzip文件。但它仍然希望压缩它。不确定是什么导致了这种行为。

这是输出(压缩语句被注释掉):

[logsync@baschinfs01 ~]$ ls -lah testdir
total 12K
drwxr-x--- 2 logsync logsync 4.0K Dec  7 17:18 .
drwxr-x--- 5 logsync logsync 4.0K Dec  7 17:33 ..
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 cat
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 dog
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 duck
-rw-r----- 1 logsync logsync    0 Nov  7 12:21 oldfile.txt
-rw-r----- 1 logsync logsync   32 Nov  7 12:21 oldfile.txt.gz
-rw-r----- 1 logsync logsync    0 Dec  7 16:12 testfile
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 testfile2
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 testfile2.gz
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 testfile3
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 testfile3.gz
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 testfile4.gz
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 testfile5
-rw-r----- 1 logsync logsync    0 Dec  7 16:12 testfile.gz
[logsync@baschinfs01 ~]$ ./test.sh
./testdir/: Gzip doesn't exist
compressing ./testdir/
./testdir/duck: Gzip doesn't exist
compressing ./testdir/duck
./testdir/dog: Gzip doesn't exist
compressing ./testdir/dog
./testdir/testfile5: Gzip doesn't exist
compressing ./testdir/testfile5
./testdir/cat: Gzip doesn't exist
compressing ./testdir/cat

以下是压缩语句的输出:

[logsync@baschinfs01 ~]$ ls -lah testdir
total 12K
drwxr-x--- 2 logsync logsync 4.0K Dec  7 17:18 .
drwxr-x--- 5 logsync logsync 4.0K Dec  7 17:35 ..
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 cat
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 dog
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 duck
-rw-r----- 1 logsync logsync    0 Nov  7 12:21 oldfile.txt
-rw-r----- 1 logsync logsync   32 Nov  7 12:21 oldfile.txt.gz
-rw-r----- 1 logsync logsync    0 Dec  7 16:12 testfile
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 testfile2
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 testfile2.gz
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 testfile3
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 testfile3.gz
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 testfile4.gz
-rw-r----- 1 logsync logsync    0 Dec  7 16:13 testfile5
-rw-r----- 1 logsync logsync    0 Dec  7 16:12 testfile.gz
[logsync@baschinfs01 ~]$ ./test.sh 
./testdir/: Gzip doesn't exist
compressing ./testdir/
gzip: ./testdir/oldfile.txt.gz already exists; do you wish to overwrite (y or n)? n
        not overwritten
gzip: ./testdir/oldfile.txt.gz already has .gz suffix -- unchanged
./testdir/duck: Gzip doesn't exist
compressing ./testdir/duck
./testdir/dog: Gzip doesn't exist
compressing ./testdir/dog
./testdir/testfile5: Gzip doesn't exist
compressing ./testdir/testfile5
./testdir/cat: Gzip doesn't exist
compressing ./testdir/cat
[logsync@baschinfs01 ~]$

正如你可以看到它仍在尝试压缩文件,即使IF条件中的其余语句被忽略。

编辑#2:最后让它与一些hackery合作。这是最终的代码,这些代码被篡改为脚本(现在直到我能找到更好的方法):

#!/bin/bash

COMPRESSWINDOWSTART=2592000
COMPRESSWINDOWEND=2678400
DATE=$(date +%s)

#Array of local directories
localDirs=("./testdir/")

#Loop through local directories
for i in "${localDirs[@]}"
        do
        echo "Entering $i directory"
#Test set FILE equal to non-gz files in current local dir
        for FILE in $(find $i ! -name "*.gz")
#If the file doesn't have a matching .gz file, compress it
                do if [ ! -e ${FILE}.gz ]
                        then
                                echo "$FILE: Gzip doesn't exist"
                                echo compressing $FILE
#test to make sure that the file is 30 days old, and if it is, gzip
                                FILEMTIME=$(stat -c %Y $FILE)
                                FILEAGE=$(($DATE-$FILEMTIME))
                                echo fileage is $FILEAGE
                                if [ $FILEAGE -gt $COMPRESSWINDOWSTART -a $FILEAGE -lt $COMPRESSWINDOWEND ]
                                        then
                                        echo $FILEAGE is greater than $COMPRESSWINDOWSTART and less than $COMPRESSWINDOWEND
                                        gzip $FILE
                                fi
                fi
                done
        done
exit

这是在我的测试用例中测试和工作的。希望它能够顺畅地融入主脚本。谢谢大家的帮助!!!!!

2 个答案:

答案 0 :(得分:1)

在最终代码中编辑。正如在依赖于find的评论中提到的那样,我认为会引起一些问题。基于它正在做什么,看起来gzip试图gzip目录中的每个文件,当它看到./testdir/作为列表中的项目之一。这避免了现在总是使用filemtime和当前日期。

答案 1 :(得分:0)

第一次编辑中的find命令忽略了之前的测试,只压缩了类型文件(-type f)和30分钟前修改过的任何内容

find $FILE -type f -mtime 30 -exec gzip {} \;

与评论#2类似,您可以执行以下操作

find $FILE -type f -not -name '*.gz' -mtime 30 -exec gzip {} \;

请记住,即使文件的扩展名不是gzip,也可以压缩文件

luis@linux:~> gzip -c talk.tmp > talk
luis@linux:~> file talk
talk: gzip compressed data, was "talk.tmp", from Unix, last modified: Mon Oct  7 15:07:10 2013