How to tar directory and then remove originals including the directory?
I'm trying to tar a collection of files in a directory called 'my_directory' and remove the originals by using the command:
tar -cvf files.tar my_directory --remove-filesHowever it is only removing the individual files inside the directory and not the directory itself (which is what I specified in the command). What am I missing here?
EDIT:
Yes, I suppose the 'remove-files' option is fairly literal. Although I too found the man page unclear on that point. (In linux I tend not to really distinguish much between directories and files that much, and forget sometimes that they are not the same thing). It looks like the consensus is that it doesn't remove directories.
However, my major prompting point for asking this question stems from tar's handling of absolute paths. Because you must specify a relative path to a file/s to be compressed, you therefore must change to the parent directory to tar it properly. As I see it using any kind of follow-on 'rm' command is potentially dangerous in that situation. Thus I was hoping to simplify things by making tar itself do the remove.
For example, imagine a backup script where the directory to backup (ie. tar) is included as a shell variable. If that shell variable value was badly entered, it is possible that the result could be deleted files from whatever directory you happened to be in last.
35 Answers
You are missing the part which says the --remove-files option removes files after adding them to the archive.
You could follow the archive and file-removal operation with a command like,
find /path/to/be/archived/ -depth -type d -empty -exec rmdir {} \;
Update: You may be interested in reading this short Debian discussion on,
Bug 424692: --remove-files complains that directories "changed as we read it".
Since the --remove-files option only removes files, you could try
tar -cvf files.tar my_directory && rm -R my_directoryso that the directory is removed only if the tar returns an exit status of 0
Have you tried to put --remove-files directive after archive name? It works for me.
tar -cvf files.tar --remove-files my_directory 2 source={directory argument}e.g.
source={FULL ABSOLUTE PATH}/my_directoryparent={parent directory of argument}e.g.
parent={ABSOLUTE PATH of 'my_directory'/logFile={path to a run log that captures status messages}Then you could execute something along the lines of:
cd ${parent}
tar cvf Tar_File.`date%Y%M%D_%H%M%S` ${source}
if [ $? != 0 ]
then echo "Backup FAILED for ${source} at `date` >> ${logFile}
else echo "Backup SUCCESS for ${source} at `date` >> ${logFile} rm -rf ${source}
fi This was probably a bug.
Also the word "file" is ambigous in this case. But because this is a command line switch I would it expect to mean also directories, because in unix/lnux everything is a file, also a directory. (The other interpretation is of course also valid, but It makes no sense to keep directories in such a case. I would consider it unexpected and confusing behavior.)
But I have found that in gnu tar on some distributions gnu tar actually removes the directory tree. Another indication that keeping the tree was a bug. Or at least some workaround until they fixed it.
This is what I tried out on an ubuntu 10.04 console:
mit:/var/tmp$ mkdir tree1 mit:/var/tmp$ mkdir tree1/sub1 mit:/var/tmp$ > tree1/sub1/file1 mit:/var/tmp$ ls -la drwxrwxrwt 4 root root 4096 2011-11-14 15:40 . drwxr-xr-x 16 root root 4096 2011-02-25 03:15 .. drwxr-xr-x 3 mit mit 4096 2011-11-14 15:40 tree1 mit:/var/tmp$ tar -czf tree1.tar.gz tree1/ --remove-files # AS YOU CAN SEE THE TREE IS GONE NOW: mit:/var/tmp$ ls -la drwxrwxrwt 3 root root 4096 2011-11-14 15:41 . drwxr-xr-x 16 root root 4096 2011-02-25 03:15 .. -rw-r--r-- 1 mit mit 159 2011-11-14 15:41 tree1.tar.gz mit:/var/tmp$ tar --version tar (GNU tar) 1.22 Copyright © 2009 Free Software Foundation, Inc.
If you want to see it on your machine, paste this into a console at your own risk:
tar --version cd /var/tmp mkdir -p tree1/sub1 > tree1/sub1/file1 tar -czf tree1.tar.gz tree1/ --remove-files ls -la