cowardly refusing to create an empty archive

Hi,
I am trying to write an Archive script that should look for files older than x days, zip them and move the zip to the archive directory and delete the files that have been zipped. I am not sure how i can handle this error:
"cowardly refusing to create an empty archieve".
Just wanted to know if there is any workaround for this. I did look into one of the threads but didn't find the answer so posted it here!!
Any help will be greatly appreciated!!!

Here is the code that i have written:
--------------------------------------------------

#!/bin/sh

FILES=/abc/def
ARCH=/fff/ddd

cd $FILES
`find . -name "*.txt" -type f -mtime +10 | xargs tar -czvf filetar.tar.gz
`mv filetar.tar.gz $ARCH`
status_check=`echo $?`
if [ $status_check -ne 0 ]; then
echo "Error"
else
echo "Success"
`find . -name "*.txt" -type f -mtime +10 | xargs rm -rf {} \;
fi

---------------------------------------------------------------

THANKS!!!!

It's being fed no files, and refuses to create an empty archive. Try leaving off the | xargs ... and see what it prints.

Add -r to the xargs. This should prevent xargs from running the tar if there isn't anything on the input.

However, you really need to reconsider using tar with xargs. If the filename arguments are long enough to cause xargs to run a second tar command you'll overwrite the first and it will appear that you only got the last n files in your archive.

Try this in a directory with a few files and see what happens:

  ls | xargs -L 1 tar -czvf foo.tar.gz
echo "contents:"
gzip -dc foo.tar.gz|tar -tvf -
 

The output from the -v will indicate that all files were passed to tar, but the table of contents will show only one file. (-L causes xargs to use at most one input line per invocation simulating what it would do if it needed to invoke multiple instances of tar)

Hey thank you so much for responding...
@corona...It works fine if i dont use xargs...as it just prints the output...but as i said i want to zip these files and move them to a safe location.
If i am not wrong..do you want me to split the "find" statement into multiple lines instead of passing "xargs"
like this:

`find . -mtime +7 -type f -name "*.txt"`
`tar -czvf sample.tar.gz`

Please let me know...

@agama..I did try your code..It printed out all the files (including zip files) in that directory and created a zip of all the mentioned files..But what i am not sure is..how would this help me out...Please make me understand!!!

Thanks Again!!!!

Which looks like what? Post a sample.

I don't see any particular reason it shouldn't work unless it's got spaces in filenames or something wacky like that.

Did you try adding -r to xarg's arguments, too?

Try this one:

#!/bin/sh

FILES=/abc/def
ARCH=/fff/ddd

cd ${FILES}
find . -name "*.txt" -type f -mtime +10 | xargs -r -t -I {} tar -czvf filetar.tar.gz "{}"
mv filetar.tar.gz ${ARCH}
status_check=$?
if [ ${status_check} -ne 0 ]
then
	echo "Error"
else
	echo "Success"
	find . -name "*.txt" -type f -mtime +10 -exec rm -f {} \;
fi

It will print all files being added to the gzip file!

# find . -name "*.txt" -type f -mtime +10 | xargs -r -t -I {} tar -czvf filetar.tar.gz "{}"
tar -czvf filetar.tar.gz ./teste2.txt
./teste2.txt
tar -czvf filetar.tar.gz ./teste.txt
./teste.txt
# ls -l filetar.tar.gz
-rw-rw-r--  1 jboss jboss 154 Nov 16 15:01 filetar.tar.gz

I hope it heps! =o)

My sample was to illustrate how using xargs with tar could lead to undesired results if xargs needs to "split" the command.

If the output from the find is more than can be placed on a single command, xargs will execute the command given (tar in your case) multiple times. With each execution the output file will be created and when finished it will contain only the files that were placed on the last command started by xargs. You may not be running into the limit now, and you might not ever hit the limit, but you could and the only symptom would be a "partial" backup.

Did you check the table of contents of the file that it created? When I ran it on my system the tar file contained only the last file printed.

---------- Post updated at 18:29 ---------- Previous update was at 18:05 ----------

I've been playing round with ways to safely use tar with xargs... I think this should work for you and will eliminate the xargs risk:

find . -name "*.txt" -type f -mtime +10 | xargs -r tar -rzvf filetar.tar.gz

Yes, there are two -r options. The one for xargs is as decribed before. Replacing the -c option on the tar command with -r causes the archive to be updated (appended to) if it exists. I tested this on both FreeBSD and Linux.

Hi Guys,
Sorry for the late reply...Thanks for your effort!!

@agama, @corona...I did try adding -r option.

This is how i have my code now!!

func()
{
cd ${dir}
`find . -mtime +90 -type f -name "*.txt" | xargs -r tar -rzvf filename.tar.gz`
`mv -f filename.tar.gz $archive`
status_check=`echo $?`
if [ $status_check -ne 0 ]; then
  echo "Archiving Unsuccessful"
else
  echo "Archiving Successful"
  `find . -mtime +90 -type f -name "*.txt" | xargs -exec rm -f {} \;`
fi
}

Since there were no files for the code to process, this is what is the output:

mv: cannot stat `filename.tar.gz': No such file or directory

Archiving Unsuccessful

Thanks!!!

---------- Post updated at 01:18 PM ---------- Previous update was at 01:16 PM ----------

Hi Guys,
Sorry for the late reply...Thanks for your effort!!

@agama, @corona...I did try adding -r option.

This is how i have my code now!!

func()
{
cd ${dir}
`find . -mtime +90 -type f -name "*.txt" | xargs -r tar -rzvf filename.tar.gz`
`mv -f filename.tar.gz $archive`
status_check=`echo $?`
if [ $status_check -ne 0 ]; then
  echo "Archiving Unsuccessful"
else
  echo "Archiving Successful"
  `find . -mtime +90 -type f -name "*.txt" | xargs -exec rm -f {} \;`
fi
}

Since there were no files for the code to process, this is what is the output:

mv: cannot stat `filename.tar.gz': No such file or directory

Archiving Unsuccessful[/b]

Thanks!!!

Why do you have all your commands in backticks? At best the backticks are useless, at worst they try to run tar's error messages as commands and cause their own errors.

Don't mv the file unless you know tar succeeded. Check first.

Don't mv the file unless you know tar did anything. Check first.

You can't use -r and -z at the same time, compress it after.

And certainly don't delete the files unless you know they're in the archive!

func()
{
        cd ${dir}
        if ! find . -mtime +90 -type f -name "*.txt" | xargs -r tar -rvf filename.tar
        then
                echo "Couldn't archive" >&2
                return 1
        fi

        [ -f "filename.tar" ] || return 1
        gzip "filename.tar" || return 1
        if ! mv -f filename.tar.gz $archive
        then
                echo "Moving Unsuccessful"
                return 1
        fi

        find . -mtime +90 -type f -name "*.txt" -exec rm '{}' ';'
}

Be a little carefull.

Say this command took a while to run:

if ! find . -mtime +90 -type f -name "*.txt" | xargs -r tar -rvf filename.tar

It could be possible that some files become older than 90days while the archive step is running. These files would then be deleted without getting to the archive.

If your tar supports it, the remove-files option might be the way to go:

if ! find . -mtime +90 -type f -name "*.txt" | xargs -r tar -rvf --remove-files filename.tar