首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BASH脚本-测试年龄和压缩文件

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

Stack Overflow用户
提问于 2011-12-08 00:54:51
回答 2查看 3.6K关注 0票数 2

首先是一些背景知识。我们有一个供应商应用程序,它生成日志和配置文件,并将它们存储在一组特定的文件夹中。它会在一段预定的时间后自动压缩日志。

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

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

代码语言:javascript
复制
#!/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的新手。

编辑:

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

代码语言:javascript
复制
#!/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文件。但它仍然想要压缩它。不确定是什么导致了这种行为。

下面是输出(将compress语句注释掉):

代码语言:javascript
复制
[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

下面是带有中的compress语句的输出:

代码语言:javascript
复制
[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:终于让它与一些黑客一起工作了。下面是脚本中的最后一段代码(在我找到更好的方法之前):

代码语言:javascript
复制
#!/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

这是在我的测试用例中测试并工作的。希望它能顺利地合并到主脚本中。感谢大家的帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-12-08 02:33:24

在最终代码中编辑。正如评论中提到的,我认为依赖于find导致了一些问题。根据它所做的事情,看起来gzip试图将目录中的每个文件作为列表中的一项进行gzip压缩。这避免了现在总是使用filemtime和当前日期。

票数 1
EN

Stack Overflow用户

发布于 2013-10-08 02:08:04

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

代码语言:javascript
复制
find $FILE -type f -mtime 30 -exec gzip {} \;

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

代码语言:javascript
复制
find $FILE -type f -not -name '*.gz' -mtime 30 -exec gzip {} \;

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

代码语言:javascript
复制
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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8419211

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档