]>
Commit | Line | Data |
---|---|---|
9855bc01 | 1 | @c This is part of the GNU tar manual. |
5c713540 | 2 | @c Copyright (C) 2017--2022 Free Software Foundation, Inc. |
9855bc01 SP |
3 | @c This file is distributed under GFDL 1.3 or any later version |
4 | @c published by the Free Software Foundation. | |
5 | ||
6 | This appendix provides several recipes for performing common tasks | |
7 | using @GNUTAR{}. | |
8 | ||
9 | @menu | |
10 | * copy directory hierarchy:: | |
11 | * intermediate directories:: | |
12 | @end menu | |
13 | ||
14 | @node copy directory hierarchy | |
15 | @appendixsec Copying directory hierarchies | |
16 | ||
17 | This is a traditional way to copy a directory hierarchy preserving | |
18 | the dates, modes, owners and link-structure of all the files therein. | |
19 | It was used back when the @command{cp} command lacked the @option{-a} | |
20 | option: | |
21 | ||
22 | @smallexample | |
23 | $ @kbd{(cd sourcedir; tar -cf - .) | (cd targetdir; tar -xf -)} | |
24 | @end smallexample | |
25 | ||
26 | @noindent | |
27 | You can avoid subshells by using @option{-C} option: | |
28 | ||
29 | @smallexample | |
30 | $ @kbd{tar -C sourcedir -cf - . | tar -C targetdir -xf -} | |
31 | @end smallexample | |
32 | ||
33 | @noindent | |
34 | The same command using long option forms: | |
35 | ||
36 | @smallexample | |
37 | @group | |
38 | $ @kbd{(cd sourcedir; tar --create --file=- . ) \ | |
39 | | (cd targetdir; tar --extract --file=-)} | |
40 | @end group | |
41 | @end smallexample | |
42 | ||
43 | @noindent | |
44 | or | |
45 | ||
46 | @smallexample | |
47 | @group | |
48 | $ @kbd{tar --directory sourcedir --create --file=- . \ | |
49 | | tar --directory targetdir --extract --file=-} | |
50 | @end group | |
51 | @end smallexample | |
52 | ||
53 | @node intermediate directories | |
54 | @appendixsec Restoring Intermediate Directories | |
55 | ||
56 | A common concern is how to extract permissions and ownerships of | |
57 | intermediate directories when extracting only selected members from | |
58 | the archive. To illustrate this, consider the following archive: | |
59 | ||
60 | @example | |
61 | @group | |
62 | # tar tvf A.tar | |
63 | drwxr-xr-x root/root 0 2017-11-16 14:39 foo/ | |
64 | dr-xr-x--- gray/user 0 2017-11-16 14:39 foo/bar/ | |
65 | -rw-r--r-- gray/user 10 2017-11-16 14:40 foo/bar/file | |
66 | @end group | |
67 | @end example | |
68 | ||
69 | Suppose you extract only the file @file{foo/bar/file}, while being | |
70 | @samp{root}: | |
71 | ||
72 | @example | |
73 | # @kbd{tar xvf A.tar foo/bar/file} | |
74 | foo/bar/file | |
75 | @end example | |
76 | ||
77 | Now, let's inspect the content of the created directories: | |
78 | ||
79 | @example | |
80 | @group | |
81 | # find foo -ls | |
82 | 427257 0 drwxr-xr-x 3 root root 16 Nov 17 16:10 foo | |
83 | 427258 0 drwxr-xr-x 2 root root 17 Nov 17 16:10 foo/bar | |
84 | 427259 0 -rw-r--r-- 1 gray user 10 Nov 6 14:40 foo/bar/file | |
85 | @end group | |
86 | @end example | |
87 | ||
88 | The requested file is restored, including its ownership and | |
89 | permissions. The intermediate directories, however, are created with | |
90 | the default permissions, current timestamp and owned by the current | |
91 | user. This is because by the time @command{tar} has reached the requested file, | |
92 | it had already skipped the entries for its parent directories, so it | |
93 | has no iformation about their ownership and modes. | |
94 | ||
95 | To restore meta information about the intermediate directories, | |
96 | you'll need to specify them explicitly in the command line and use the | |
97 | @option{--no-recursive} option (@pxref{recurse}) to avoid extracting | |
98 | their content. | |
99 | ||
100 | To automate this process, @cite{Neal P. Murphy} proposed the following | |
101 | shell script@footnote{The original version of the script can be | |
102 | seen at @uref{http://lists.gnu.org/archive/html/bug-tar/2016-11/msg00024.html}}: | |
103 | ||
104 | @example | |
105 | @group | |
106 | #! /bin/sh | |
107 | (while read path | |
108 | do | |
109 | path=`dirname $path` | |
110 | while [ -n "$path" -a "$path" != "." ] | |
111 | do | |
112 | echo $path | |
113 | path=`dirname $path` | |
114 | done | |
115 | done < $2 | sort | uniq) | | |
116 | tar -x --no-recursion -v -f $1 -T - -T $2 | |
117 | @end group | |
118 | @end example | |
119 | ||
120 | The script takes two arguments: the name of the archive file, and the | |
121 | name of the file list file. | |
122 | ||
123 | To complete our example, the file list will contain single line: | |
124 | ||
125 | @example | |
126 | foo/bar/file | |
127 | @end example | |
128 | ||
129 | Supposing its name is @file{file.list} and the script is named | |
130 | @file{restore.sh}, you can invoke it as follows: | |
131 | ||
132 | @example | |
133 | # @kbd{sh restore.sh A.tar file.list} | |
134 | @end example |