tar leading period slash
Solution 1:
Try the --xform
option, which uses a sed-like replace expression. This allows you to change the path references going into the archive rather than handle it during the extraction (such as with the --strip-components).
tar --exclude=.gitignore -cz --xform s:'./':: -f dist.tgz ./
To list the files as they are processed, add the -v
and --show-transformed-name
options:
tar --exclude=.gitignore -cvz --xform s:'./':: --show-transformed-name -f dist.tgz ./
The argument to pass --xform follows this structure: s/regexp/replace/[flags]
Note that in my example, I used :
as a delimter; you can use any character you want so long as you use it consistently. Good reference here.
Solution 2:
There are a number of ways to accomplish this, many of which have already been hinted at in this question, some of which have not. This is my attempt to compile them all (with references) and show examples for easy reading, allowing the reader to pick and choose one to fit his or her needs.
Example Input Tree
This is the structure that’s going to be tar’d up in the following examples.
.dotfile
dir/
.hidden
file.txt
root.txt
POSIX (Cross-Platform, Cross-Shell) Solution
You may be able to use use pax instead of tar, as Phil P. pointed out.
Usual behavior:
$ pax -wzvf ../ball.tar.gz .
[…]
$ pax -zf ../ball.tar.gz
.
./.dotfile
./dir
./dir/.hidden
./dir/file.txt
./root.txt
No dot-slash:
$ pax -wzvf ../ball.tar.gz -s ':^\./::' .
[…]
$ pax -zf ../ball.tar.gz
.
.dotfile
dir
dir/.hidden
dir/file.txt
root.txt
Shell Globbing (Cross-Platform) Solution
You may also be able to use *
instead of .
, as ott-- pointed out. This solution is basically a short-hand form of chutz’s answer, since the shell will expand the asterisk in the example below to all non-hidden files before passing them along as arguments to the tar
program.
No dot-slash (but note the missing root-level .dotfile
):
$ tar -czvf ../ball.tar.gz *
[…]
$ tar -tzf ../ball.tar.gz
dir/
dir/.hidden
dir/file.txt
root.txt
If you don’t care about packing dot-files in the CWD, you’re done.
If you do care, you’re not without recourse. On many shells (e.g. bash
) it may be possible to include dot-files in the shell glob by changing a shell option. With bash, this is done with shopt:
dotglob
If set, bash includes filenames beginning with a '.' in the results of pathname expansion.
$ shopt -s dotglob # Include dot-files in pathname expansions
$ tar -czvf ../ball.tar.gz *
[…]
$ shopt -u dotglob # Restore shell's default globbing behavior
$ tar -tzf ../ball.tar.gz
.dotfile
dir/
dir/.hidden
dir/file.txt
root.txt
GNU (Linux) Solution
Use --xform as mentioned in Jordan Bonitatis’s answer.
Usual behavior:
$ tar -czvf ../ball.tar.gz .
[…]
$ tar -tzf ../ball.tar.gz
./
./root.txt
./.dotfile
./dir/
./dir/file.txt
./dir/.hidden
No dot-slash:
$ tar -czvf ../ball.tar.gz --xform 's:^\./::' . [--show-transformed-names|--show-stored-names]
[…]
$ tar -tzf ../ball.tar.gz
./
root.txt
.dotfile
dir/
dir/file.txt
dir/.hidden
BSD (Mac OS X) Solution
Use -s, which is deceptively similar to pax/sed, but not quite, as shown below.
Usual behavior:
$ tar -czvf ../ball.tar.gz .
[…]
$ tar -tzf ../ball.tar.gz
./
./.dotfile
./dir/
./root.txt
./dir/.hidden
./dir/file.txt
No dot-slash:
$ tar -czvf ../ball.tar.gz -s '/.//' .
tar: Removing leading '/' from member names
[…]
$ tar -tzf ../ball.tar.gz
.dotfile
dir/
root.txt
dir/.hidden
dir/file.txt
Solution 3:
Not sure what version of tar
this is, but normally you have to specify what files you want to archive. Like tar c .
to compress everything in the local directory. Running your command on my machine I get:
tar: Cowardly refusing to create an empty archive
So, if you don't want to get the leading ./
, which is what you get when you compress the local directory .
, you can simply specify the files directly. For example:
> tar c hosts fstab | tar tv
-rw-r--r-- root/root 1225 2012-10-20 13:37 hosts
-rw-r--r-- root/root 678 2012-05-13 22:09 fstab
Solution 4:
I've used tar -P
to preserve the leading /
(rather than ./
) It's not entirely clear if this would help in your case, though.
-P, --absolute-names
don't strip leading '/'s from file names
man tar
Solution 5:
In the old versions of tar, it used to use the full path names you provided, in the tar, but this is somehow problematic as one might want a second copy of something and an unintentional expansion of the tar archive in the old format days, might overwrite an existing file or files.
So, in most recent versions of tar binary, distributed in almost any linux distribution, puts the ./ at the beginning of each file it packs up, so that, an unintentional expansion, expands the archive into your current working directory and below.
I am not sure why it is causing such a problem for you. if you are in the right directory level, where you want to expand this archive into, it will do just that. For instance, lets say you have a file as
/tmp/myarchive.tar
and let's assume the contents of the archive are
./etc/hosts ./etc/profile ./etc/passwd ./etc/group
if you expand this archive while your current working directory is / (i.e. root level), these files will go and overwrite the existing
/etc/hosts /etc/profile /etc/passwd /etc/group
if this is what you want, you've got it. But let's say, you only wanted the hosts files out of this archive but all of a sudden you obliterated profile passwd and group files. Hope you have a good backup at this point, so that you can get them back
But, if you are the type of sysadmin, who avoids being in the root level, unless he/she needs it intentionally, you are most probably logged in ans located under /home/some-user or if you logged in as root, you are in /root directory. Let's say your in /root. when you execute the command
# tar -xvf /tmp/myarchive.tar
you will end up with
/root/etc/hosts /root/etc/profile /root/etc/passwd /root/etc/group
no harm, no foul. Then
# mv /root/etc/hosts /etc/hosts
Voila. You accomplished your goal.