我知道这是基本问题,但请帮助我。我使用tar
命令压缩并存档我的服务器日志文件
for i in server.log.2016-07-05 server.log.2016-07-06 ; do tar -zcvf server2.tar.gz $i; done
上述循环的输出是
server.log.2016-07-05
server.log.2016-07-06
但是,在使用tar -tvf server2.tar.gz
获得的输出列出文件时,
rw-r--r-- root/root 663643914 2016-07-06 23:59 server.log.2016-07-06
即,我存档了两个文件,但只显示了一个文件,这意味着存档不包含这两个文件,存档必须包含所有文件。请帮忙解决这个问题。
我刚刚测试了这两个文件,但我的文件夹有多个文件。由于我没有得到预期的输出,所以我没有继续处理文件夹中的所有文件。我要使用的确切循环是
Previousmonth=$(date "+%b" --date '1 month ago')
for i in $(ls -l | awk '/'$Previousmonth'/ && /server.log./ {print $NF}');do;tar -zcvf server2.tar.gz $i;done
答案1
每次执行循环时,tar
都会执行命令put一文件到文件server2.tar.gz
。该文件最终将只有一个文件。
使用 tar 选项附加文件:
tar --append -zcvf server2.tar.gz "$i"
或者只是将文件列表提供给 tar (请不要使用此命令):
tar -zcvf server2.tar.gz $(ls -l|awk '/'$Previousmonth'/&&/server.log./{print $NF}')
但是,该命令行存在一些问题:
- 解析
ls
输出(错误)。 - 使用
$Previousmonth
不带引号的(错误)。 - 构建可能包含嵌入空格的文件列表(不可靠)。
使用此(一对)命令代替:
month=$(date "+%Y-%m-" --date '1 month ago')
find ./ -name "server.log.${month}*" -exec tar -zcvf server2.tar.gz '{}' \+
答案2
回答原来的问题
解决方案是不使用for
循环。它每次都会覆盖该文件。相反,使用:
tar -zcvf server2.tgz server.log.2016-07-05 server.log.2016-07-06
这会将命令行上列出的文件数量添加到同一存档中。
回答修改后的问题
要压缩 7 月份的所有文件:
tar -zcvf server2.tgz server.log.2016-07-*
或者,压缩上个月的所有文件,无论它是什么:
tar -zcvf server2.tgz server.log.$(date "+%Y-%m" --date '1 month ago')-*
答案3
@John1024 已经给你了一个很好的答案,但我想我应该补充一点。
在某些情况下,你可能想要将文件添加到现有tar
存档。例如,您有每个月的日志文件存档,并且希望在午夜可能发生的日志文件轮换之后,每晚将每日日志文件添加到该存档中。
如果您的归档文件是/data/logs/logfiles-2016-08.tar
在 8 月调用的,并且轮换的日志文件本身在特定日期被调用/var/log/servicename-2016-08-06.log
(对于 的许多不同值servicename
),您可以有一个 cron 作业在凌晨 3 点调用的小脚本,该脚本执行以下操作:
#!/bin/sh
yyyymm="$( date --date="1 day ago" +"%Y-%m" )"
yyyymmdd="$( date --date="1 day ago" +"%Y-%m-%d" )"
for logfile in /var/log/*-$yyyymmdd.log; do
tar -r -C /var/log -f "/data/logs/logfiles-$yyyymm.tar" "${logfile##*/}" &&
rm "${logfile##*/}"
done
该-r
标志指示tar
将条目附加到存档中。该-C
标志用于指示在访问日志文件之前tar
更改目录。/var/log
该-f
标志指定存档的位置。将${logfile##*/}
扩展为日志文件的基本名称(不带路径的文件名)(可以替换为$(basename "$logfile")
)。
在每个月初,您可以使用以下命令压缩上个月的日志文件存档
#!/bin/sh
yyyymm="$( date --date="1 month ago" +"%Y-%m" )"
gzip --best "/data/logs/logfiles-$yyyymm.tar"
这比直接做要麻烦一点
cd /var/log &&
tar -c -z -f /data/logs/logfiles-2016-08.tar.gz *-2016-08-??.log &&
rm *-2016-08-??.log
每月一次,但仍然可能有这样做的理由。
注意:可以使用 向存档中添加文件tar -r
,但存档不能是压缩档案当时(GNUtar
可能支持这一点)。如果存档不存在,则会创建它。另请注意,我上面的示例需要 GNU date
。