for 循环中的 tar 命令

for 循环中的 tar 命令

我知道这是基本问题,但请帮助我。我使用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

相关内容