2

In order to make the unpacking process as robust as possible I would like for a tar(.gz) archive to be unpacked in a certain order so that a power outage or such is less likely to cause harm.

As an example, I have the following directory tree:

.
├── b
└── foo
    ├── a
    └── c

and I want them to be unpacked in the order

./foo/a
./b
./foo/c

I plan on using GNU tar with the --format=oldgnu option (to keep compatible with Busybox' tar) in bash. I would be open to using other tools as well, the format is necessary though.

Using A/--append this should be possible (or so I thought). But somehow I failed in all my attempts so far, e.g.:

  • $ tar c ./foo/a | tar A ./b > test.tar
    tar: Options '-Aru' are incompatible with '-f -'
    
  • $ tar Af <(tar c ./foo/a) ./b > test.tar
    tar: Cannot backspace archive file; it may be unreadable without -i
    tar: /dev/fd/63: Cannot write: Bad file descriptor
    tar: Error is not recoverable: exiting now
    

(I tested without the format option and without the ./foo/c file at first.)

  • I see roaima has already provided a good answer; just an outside-the-box comment from me: what about packaging the files together in multiple tar files, grouped in some sort of "safe" order? You could package the set of tar files together into one overarching one if desired, then just add a set of un-tarring commands for the set, in sequence. – Jeff Schaller Jun 27 '16 at 19:21
  • @JeffSchaller Interesting idea but hardly possible for, since I need to be compatible with a certain update procedure already in place. – phk Jun 27 '16 at 19:26
4

tar will unpack its archive in the order that it was created.

( echo foo; echo foo/a; echo b; echo foo/c ) | tar --no-recursion --files-from=- -cvf /tmp/tar.tar

and

tar tvf /tmp/tar.tar
drwxr-xr-x roaima/roaima 0 2016-06-27 20:20 foo/
-rw-r--r-- roaima/roaima 0 2016-06-27 20:20 foo/a
-rw-r--r-- roaima/roaima 0 2016-06-27 20:13 b
-rw-r--r-- roaima/roaima 0 2016-06-27 20:20 foo/c
  • BTW, a subshell is not needed. For whom it may concern, here is how I am using it now (./foo/b in my question was a placeholder for actually numerous files, therefore the find): { printf "%s\n%s\n%s\n" './' './foo' './foo/a'; find '.' -mindepth 1 ! \( -path './foo' -prune \); echo './foo/c'; } | tar --files-from=- --no-recursion -cvf "../archive.tar" – phk Jul 15 '16 at 15:29
  • @phk the subshell in my example is to build the example that illustrates the statement. Nothing more. – roaima Jul 15 '16 at 15:30
  • Note that in the newest tar versions (e.g. 1.28) the position of --no-recursion matter and it has to come before --files-from=- in this case. – phk Jul 20 '16 at 17:28
  • Ah OK, according to gnu.org/software/tar/manual/html_section/tar_22.html#SEC44 --recursion/--no-recursion is position-relevant now. See also lists.gnu.org/archive/html/bug-tar/2016-05/msg00008.html – phk Jul 20 '16 at 18:10
  • @phk thank you. That's a big change to behaviour (but I can understand the rationale that an argument should affect subsequent actions). – roaima Jul 20 '16 at 18:25

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.