I have the following command in the part of a backup shell script:
tar -cjf site1.bz2 /var/www/site1/
When I list the contents of the archive, I get:
tar -tf site1.bz2
var/www/site1/style.css
var/www/site1/index.html
var/www/site1/page2.html
var/www/site1/page3.html
var/www/site1/images/img1.png
var/www/site1/images/img2.png
var/www/site1/subdir/index.html
But I would like to remove the part /var/www/site1
from directory and file names within the archive, in order to simplify extraction and avoid useless constant directory structure. Never know, in case I would extract backuped websites in a place where web data weren't stored under /var/www
.
For the example above, I would like to have :
tar -tf site1.bz2
style.css
index.html
page2.html
page3.html
images/img1.png
images/img2.png
subdir/index.html
So, that when I extract, files are extracted in the current directory and I don't need to move extracted files afterwards, and so that sub-directory structures is preserved.
There are already many questions about tar and backuping in stackoverflow
and at other places on the web, but most of them ask for dropping the entire sub-directory structure (flattening), or just add or remove the initial / in the names (I don't know what it changes exactly when extracting), but no more.
After having read some of the solutions found here and there as well as the manual, I tried :
tar -cjf site1.bz2 -C . /var/www/site1/
tar -cjf site1.bz2 -C / /var/www/site1/
tar -cjf site1.bz2 -C /var/www/site1/ /var/www/site1/
tar -cjf site1.bz2 --strip-components=3 /var/www/site1/
But none of them worked the way I want. Some do nothing, some others don't archive sub-directories anymore.
It's inside a backup shell script launched by a Cron, so I don't know well, which user runs it, what is the path and the current directory, so always writing absolute path is required for everything, and would prefer not changing current directory to avoid breaking something further in the script (because it doesn't only backup websites, but also databases, then send all that to FTP etc.)
How to achieve this?
Have I just misunderstood how the option -C works?
-C
just means "change directory", while replacing a path (or prefixing) can be only done by --transform
. rif. superuser.com/questions/595510/prepend-prefix-in-tar/595512 you can simple -C (change directory) and --transform it: ``` tar cjf site1.bz2 --transform "s/^\.\//$targetbase/" -C /var/www/site1 . ```
tar -cjf site1.tar.bz2 -C /var/www/site1 .
In the above example, tar will change to directory /var/www/site1
before doing its thing because the option -C /var/www/site1
was given.
From man tar
:
OTHER OPTIONS
-C, --directory DIR
change to directory DIR
The option -C
works; just for clarification I'll post 2 examples:
creation of a tarball without the full path: full path /home/testuser/workspace/project/application.war and what we want is just project/application.war so: tar -cvf output_filename.tar -C /home/testuser/workspace project Note: there is a space between workspace and project; tar will replace full path with just project . extraction of tarball with changing the target path (default to ., i.e current directory) tar -xvf output_filename.tar -C /home/deploy/ tar will extract tarball based on given path and preserving the creation path; in our example the file application.war will be extracted to /home/deploy/project/application.war. /home/deploy: given on extract project: given on creation of tarball
Note : if you want to place the created tarball in a target directory, you just add the target path before tarball name. e.g.:
tar -cvf /path/to/place/output_filename.tar -C /home/testuser/workspace project
Seems -C
option upto tar v2.8.3 does not work consistently on all the platforms (OSes). -C
option is said to add directory to the archive but on Mac and Ubuntu it adds absolute path prefix inside generated tar.gz file.
tar target_path/file.tar.gz -C source_path/source_dir
Therefore the consistent and robust solution is to cd
in to source_path (parent directory of source_dir) and run
tar target_path/file.tar.gz source_dir
or
tar -cf target_path/file.tar.gz source_dir
in your script. This will remove absolute path prefix in your generated tar.gz file's directory structure.
-cvf
added after tar
), I find the resulting tar.gz file does not have absolute paths inside of it, which is consistent with several other answers. If you think tar is broken or outdated on both of the systems I've used for testing, please link to some documentation that would support your answer. I think the -C
option changes directory before executing (as in other answers). When I omit it, tar tries to add junk from ./
, including paths from starting from ./
.
cd
first. Your answer says the tool works in the opposite way of how the docs say it works and how it works on my system, so it's a wrong answer. You could easily fix it.
One minor detail:
tar -cjf site1.tar.bz2 -C /var/www/site1 .
adds the files as
tar -tf site1.tar.bz2
./style.css
./index.html
./page2.html
./page3.html
./images/img1.png
./images/img2.png
./subdir/index.html
If you really want
tar -tf site1.tar.bz2
style.css
index.html
page2.html
page3.html
images/img1.png
images/img2.png
subdir/index.html
You should either cd into the directory first or run
tar -cjf site1.tar.bz2 -C /var/www/site1 $(ls /var/www/site1)
ls -A
you get hidden files too, WITHOUT trying to traverse the ..
and .
files which is a common source of confusing if doing a tar or rsync where it tries to resolve symlinks.
The following command will create a root directory "." and put all the files from the specified directory into it.
tar -cjf site1.tar.bz2 -C /var/www/site1 .
If you want to put all files in root of the tar file, @chinthaka is right. Just cd in to the directory and do:
tar -cjf target_path/file.tar.gz *
This will put all the files in the cwd to the tar file as root files.
Using the "point" leads to the creation of a folder named "point" (on Ubuntu 16).
tar -tf site1.bz2 -C /var/www/site1/ .
I dealt with this in more detail and prepared an example. Multi-line recording, plus an exception.
tar -tf site1.bz2\
-C /var/www/site1/ style.css\
-C /var/www/site1/ index.html\
-C /var/www/site1/ page2.html\
-C /var/www/site1/ page3.html\
--exclude=images/*.zip\
-C /var/www/site1/ images/
-C /var/www/site1/ subdir/
/
.
, which is the current directory. In the context of the tar.gz
's structure, that's just the base/root/top level, right?
If you want to archive a subdirectory and trim subdirectory path this command will be useful:
tar -cjf site1.bz2 -C /var/www/ site1
Found tar -cvf site1-$seqNumber.tar -C /var/www/ site1
as more friendlier solution than tar -cvf site1-$seqNumber.tar -C /var/www/site1 .
(notice the . in the second solution) for the following reasons
Tar file name can be insignificant as the original folder is now an archive entry
Tar file name being insignificant to the content can now be used for other purposes like sequence numbers, periodical backup etc.
Success story sharing
tar
to archive everything in the current directory. And-C
sets the current directory.tar -czvf site1.tar.gz -C /var/www/ site1
(Note the space, I'm still using the -C, to cd to the parent dir, and specifying the dir to tar instead of dot)./folders
how can this be removed?