根据新信息,我重新表述了这个问题。下面是旧信息,以免使基于旧信息的答案和评论无效。
我有一个tarball.tar
想要提取的tarball destination
,该目录与我当前的工作目录不同,因此我使用 tar 的-C
选项,它可以实现我想要的功能。
但是,如果我尝试指定要从 tarball 中提取的文件,则该-C
选项似乎被忽略。文件被提取到我当前的工作目录中。
tar -xf tarball.tar -C destination
Tar 的版本是
$ tar --version
tar (GNU tar) 1.28
这是一个错误还是我的理解有-C
误?
最小工作示例
下面是一个 bash 脚本来展示该行为。将其存储(或执行)在一个空目录中
#!/bin/bash -x
set -e # Abort if any of these commands fails
touch file1 file2 file3 # Create files to be archived
tar -cf tarball.tar file1 file2 file3 # Create the archive
rm file1 file2 file3 # Remove source files
tar -tf tarball.tar # Should contain files 1–3
mkdir -p destination # Create destination directory
tar -xf tarball.tar file1 file2 -C destination # Extract two files from
#+ tarball into destination directory
ls . # Should contain only the script itself,
#+ tarball.tar, and destination
ls destination # Should contain file1 and file 2
如果我执行脚本,destination
则为空并ls .
返回
$ ls .
file1 file2 tarball.tar tar.sh
如果我没有指定要提取的文件(因此
tar -xf tarball.tar file1 file2 -C destination
第 9 行变成
tar -xf tarball -C destination
),则行为将符合预期。ls destination
显示file1 file2 file3
。
老问题(忽略此问题)
我有一个 tar 档案/path/to/backup.tar.gz
,其中包含目录home/bleistift2/stuff
和home/bleistift2/more_stuff
。
为了将这两个目录提取到/home/bleistift2/tmp
(文件系统中,而不是存档中),我发出以下命令。我的理解是-C
指定提取位置。目标目录存在。
tar -zxvf /path/to/backup.tar.gz \ # The archive to extract
home/bleistift2/stuff home/bleistift2/more_stuff \ # The contents to extract
--same-owner -C /home/bleistift2/tmp # The destination directory
但是,目录是作为档案的兄弟存储的,因此我最终使用了/path/to/home/bleistift2/{stuff, more_stuff}
而不是/home/bleistift2/tmp/home/bleistift2/{stuff, more_stuff}
。
答案1
-C
工作原理如下cd
:
$ tar -tf test.tar
a
b
$ ls -Al dst1/
total 0
$ ls -Al dst2/
total 0
$ tar -xvf test.tar -C dst1/ a -C ../dst2/ b
a
b
$ rm -v dst*/*
removed 'dst1/a'
removed 'dst2/b'
$ (TAR=$(realpath test.tar); cd dst1/; tar -xvf "$TAR" a; cd ../dst2/; tar -xvf "$TAR" b)
a
b
$ rm -v dst*/*
removed 'dst1/a'
removed 'dst2/b'
$
是的,顺序很重要。
答案2
更新:这个答案是在编辑问题之前按照理解解决问题的,所以事实证明它不是所报告的实际问题的答案。我很快就会删除这个答案。
tar 提取的文件将包含完整路径名,从开始提取的地方开始。
因此,如果文件存储在名为 的 tarball 中home/bleistift2/stuff
,并且您将其解压缩到 下/home/bleistift2/tmp/
,那么您最终会得到/home/bleistift2/tmp/home/bleistift2/stuff
,因为 tar 没有很好的方法来知道您想要在解压缩过程中删除主目录前缀......
您可以通过向 tar 传递--strip-components
选项来控制提取过程中的此行为。
来自tar(1) 手册页:
--strip-components
=
数字条数字提取文件名中的前导组件
在您的具体情况下:
$ tar -zxvf /path/to/backup.tar.gz \
home/bleistift2/stuff home/bleistift2/more_stuff \
--same-owner -C /home/bleistift2/tmp \
--strip-components=2
删除 2 个组件将删除基本home/
目录以及用户的主目录。这似乎正是您在特定情况下想要的。
作为更一般的建议,尝试防止在创建时解决这个问题,通过不存储 tarball 中不相关或不需要的文件路径部分,这在提取时非常有用。
不要使用绝对路径(或根目录的完整路径):
$ tar -czvf /path/to/backup.tar.gz /home/bleistift2
将目录更改为主目录并打包当前目录:
$ cd /home/bleistift2
$ tar -czvf /path/to/backup.tar.gz .
这样,文件将作为档案存储./stuff
在./more_stuff
档案内,并且您在提取时无需剥离任何组件。
您还可以使用-C
选项来更改目录,这相当于上面的命令:
$ tar -czvf /path/to/backup.tar.gz -C /home/bleistift2 .