33

I am making an RPM in which everything is contained in the .spec file (don't ask :-). rpmbuild requires a "Source" file, so I was trying to create an empty tar file. However, if I don't give any filenames, tar complains:

tar: Cowardly refusing to create an empty archive
Try `tar --help' or `tar --usage' for more information.

How do I create a truly empty tar file?

2
  • its been answered before here: superuser.com/questions/133186/…
    – Rhyuk
    Jul 13 '12 at 19:07
  • 3
    Actually, @Rhuyuk, it hasn't. That post is someone who forgot to list a filename, and the answer helped them realize they needed to pass another argument, resulting in a non-empty archive. This is why I changed the title of that question, and created this question, which DOES answer what the title of that question was asking. Jul 13 '12 at 19:13
33

You can force GNU and BSD tar to create an empty archive with:

tar -cf tarfilename.tar -T /dev/null
6
  • ya, 'f' option must be last, as it specifies the filename. You're going to create an archive named T, but it'll error on missing tarfilename.tar file anyways.
    – lornix
    Jul 14 '12 at 19:41
  • 1
    One reason to create an empty tar: scripted tar creation. Step 1: Create the tar. Step 2: Add files one by one. You can do this with an "if first file then create else then append" but that's not as smooth. Nov 29 '12 at 17:53
  • 4
    @dpk: If I understand what you are saying, why don't you just always use append? Append will create the tar file if it doesn't already exist, so you don't need to check if it's the first file, just append and if it's the first file tar will create it. Dec 16 '12 at 2:42
  • 1
    @SeanReifschneider It looks like that'd work fine. Nice. Dec 17 '12 at 23:14
  • 1
    @SeanReifschneider: +1 for the hint that append mode creates the archive for the first file if it's not already on disk. I'm using find command to exec tar in append mode in a script so didn't need to create the archive file before-hand.
    – GuruM
    Jul 29 '13 at 8:40
11

If you have GNU tar

Either using /dev/null

$ tar -cf empty.tar --files-from /dev/null

Or by reading EOF from standard input.

$ printf '' | tar -cf empty.tar --files-from -

If you don't have tar

An empty tar file is just a file with 10240 NUL bytes in it. So to create an empty tar file, you don't even need tar but instead can use either of these:

$ head --bytes=10240 /dev/zero > empty.tar
$ truncate --size=10240 empty.tar
$ fallocate --length=10240 empty.tar
$ dd if=/dev/zero bs=10240 count=1 iflag=fullblock > empty.tar
$ dd if=/dev/zero bs=1 count=10240 > empty.tar

Why does this work?

https://www.gnu.org/software/tar/manual/html_node/Standard.html

Physically, an archive consists of a series of file entries terminated by an end-of-archive entry, which consists of two 512 blocks of zero bytes.

At the end of the archive file there are two 512-byte blocks filled with binary zeros as an end-of-file marker.

So in practice, it's sufficient to write 1024 zero bytes (two times 512 byte blocks) into a file to obtain an empty archive:

$ head --bytes=1024 /dev/zero > empty.tar
$ tar tvf empty.tar

If we only write 1023 zeros and a single 'one' into a file, tar will complain because instead of two blocks filled with all zeros, it only found one block with all zeros (the first) while the second was not all zeros:

$ { head --bytes=1023 /dev/zero; printf '\001' } > empty.tar
$ tar tvf empty.tar
tar: A lone zero block at 1

But why not just 1024 zero bytes but 10240 instead? The reason is blocking or the default record size or the blocking factor:

https://www.gnu.org/software/tar/manual/html_section/tar_76.html

The default blocking factor is 20. With a block size of 512 bytes, we get a record size of 10240. And tar will always pad the tarball such that its size is a multiple of the record size:

Some devices requires that all write operations be a multiple of a certain size, and so, tar pads the archive out to the next record boundary.

9
  • @KamilMaciorowski thanks for your hints about dd usage! I learned something new! About answering the right question: The title indeed asks "how to force tar" but when reading the question text, it becomes clear, that OP actually wants an empty tar file and it should not matter how.
    – josch
    Jan 15 '19 at 6:58
  • I went ahead and edited the question. Jan 15 '19 at 7:30
  • "just a file with 10240 NUL bytes in it" source for that?
    – Mr. Roland
    Apr 24 '20 at 10:51
  • @Mr.Roland gnu.org/software/tar/manual/html_node/Standard.html "terminated by an end-of-archive entry, which consists of two 512 blocks of zero bytes" -- each block is 20 bytes and 512 times 20 is 10240
    – josch
    Apr 25 '20 at 11:19
  • Or as empirical evidence: tar --create --files-from /dev/null | wc -c will give a file with 10240 zeros.
    – josch
    Apr 25 '20 at 11:21
9

BSD: tar cvf empty.tar --from-file /dev/null

GNU (Linux): tar cvf empty.tar --files-from /dev/null

Solaris: tar cvf empty.tar -I /dev/null

1
  • Finally something that works in Solaris!! Thanks a lot
    – AJPerez
    Nov 23 '16 at 9:03
3

I was able to create an empty archive by archiving a single file, then deleting the file from the archive.

tar cf empty.tar somefile                   # creates archive
tar --delete -f empty.tar somefile          # remove the file
tar tf empty.tar                            # list contents of archive

This works for me.

1
  • 2
    I can verify that with GNU tar this will produce the expected 10K file of all NUL characters. Jul 22 '12 at 6:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.