4
0

recipes.texi 3.7 KB

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