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.