0

I know it is the basic question but please do help me. I compressed and archived my server log file using tar command

for i in server.log.2016-07-05 server.log.2016-07-06 ; do tar -zcvf  server2.tar.gz $i; done

the output of the above loop is

server.log.2016-07-05
server.log.2016-07-06

But while listing the file using tar -tvf server2.tar.gz the output obtained is

rw-r--r-- root/root 663643914 2016-07-06 23:59 server.log.2016-07-06

i.e., I archived two files but only one file was displayed which means archive doesn't have both files, archive must have all the files. Please help on this.

I just tested with these two files but my folder has multiple files.Since I didnt get expected output I was not proceeded with all the files in my folder.The exact loop I am going to use is

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
  • if there are only two files then why do you want to use for loop ? simply use tar -cvzf name.tar.gz file1 file2. and looking at the log files, I guess you should have look at logrotate. – Rahul Aug 6 '16 at 5:28
  • Rahul,directory doesnt have two files it has multiple files.I tested with two files. I edited the question by adding the loop i am going to use.Please have a look – karthik Aug 6 '16 at 5:51
  • that means you want to compress files which are older than 30 days ? – Rahul Aug 6 '16 at 6:06
  • need to compress the file at beginning of month , why i didn't mention 30 days is some months may have 30 or 31 days right – karthik Aug 6 '16 at 6:08
  • Aside: you can use tar -A instead of tar -c to concatenate (add) files to an existing archive. Though it doesn't work in combination with compression; you'd need to run the archive through gzip in the end. – ilkkachu Aug 6 '16 at 11:34
2

Each time the loop is executed, the command tar is executed to put one file to the file server2.tar.gz. The file will end having only one file.

Either use tar option to append files:

tar --append -zcvf server2.tar.gz "$i"

or just give the list of file to tar (please don't use this command):

tar -zcvf server2.tar.gz  $(ls -l|awk '/'$Previousmonth'/&&/server.log./{print $NF}')

However, that command line has some issues:

  • parsing ls output (wrong).
  • using $Previousmonth un-quoted (wrong).
  • building a list of files that may have embedded spaces (in-reliable).

use this (pair of) command(s) instead:

month=$(date "+%Y-%m-" --date '1 month ago')
find ./ -name "server.log.${month}*" -exec tar -zcvf server2.tar.gz '{}' \+
3

Answer for original question

The solution is not to use a for loop. It overwrites the file each time. Instead, use:

tar -zcvf server2.tgz server.log.2016-07-05 server.log.2016-07-06

This adds as many files as you list on the command line to the same archive.

Answer for revised question

To compress all files from July:

tar -zcvf server2.tgz server.log.2016-07-*

Or, to compress all files from the previous month, whatever it was:

tar -zcvf server2.tgz server.log.$(date "+%Y-%m" --date '1 month ago')-*
  • John , My folder has multiple files , have edited my question.Please advice on that If for loop overwrites the file each time what is the solution – karthik Aug 6 '16 at 5:55
  • @karthikraj I have updated the answer with a method to tar all of the July files. – John1024 Aug 6 '16 at 6:10
  • John,Thanks for the reply.Problem is i need to do the same at beginning of all the months so i have planned to execute through crontab.your revised answer will be interactive in that situation right (server.log.20** - *- *).How to solve this. – karthik Aug 6 '16 at 6:19
  • 1
    @karthikraj Use tar -zcvf server2.tgz server.log.$(date "+%Y-%m" --date '1 month ago')-* – John1024 Aug 6 '16 at 6:27
1

@John1024 already gave you a good answer, but I thought I'd add a bit more.

Under some circumstances, you may want to add files to an existing tar archive. For example, you have an archive of log files for each month and you want to add the daily log files to that archive every night after the log file rotation that might happen at midnight.

If your archive is called /data/logs/logfiles-2016-08.tar for August and the rotated log files themselves, for a particular date, are called /var/log/servicename-2016-08-06.log (for a number of different values of servicename) you could have a small script that a cron job calls at 3am that does

#!/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

The -r flag tells tar to append entries to the archive. The -C flag is used to tell tar to change directory to /var/log before accessing the log files. The -f flag specifies the location of the archive. The ${logfile##*/} will expand to the basename (the filename without path) of the logfile (this may be replaced with $(basename "$logfile")).

At the beginning of each month, you may compress the log file archive of the previous month with

#!/bin/sh

yyyymm="$( date --date="1 month ago" +"%Y-%m" )"

gzip --best "/data/logs/logfiles-$yyyymm.tar"

This is a bit more cumbersome than just doing

cd /var/log &&
tar -c -z -f /data/logs/logfiles-2016-08.tar.gz *-2016-08-??.log &&
rm *-2016-08-??.log

once a month, but there might be reasons for doing it nonetheless.

Note: A file may be added to an archive with tar -r, but the archive can not be a compressed archive at the time (GNU tar may support that though). If the archive does not exist, it will be created. Also note that my examples above requires GNU date.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.