焦油领先期的斜线

tar czf dist.tgz –exclude =“。gitignore”。

这将在tar中创build带有前导“./”的文件,而后者在服务器需要提取部分tar时会变成问题。

有人能告诉我如何包装它,所以不会有领先的“./”?

尝试使用类似于sed的replaceexpression式的--xform选项。 这允许您更改进入存档的path引用,而不是在提取期间处理它(例如使用–strip-components)。

 tar --exclude=.gitignore -cz --xform s:'./':: -f dist.tgz ./ 

要列出正在处理的文件,请添加-v--show-transformed-name选项:

 tar --exclude=.gitignore -cvz --xform s:'./':: --show-transformed-name -f dist.tgz ./ 

传递–xform的参数遵循以下结构: s/regexp/replace/[flags]请注意,在我的示例中,我使用:作为分隔符; 你可以使用任何你想要的angular色,只要你一直使用它。 这里很好的参考。

有很多方法可以做到这一点,其中许多已经在这个问题上暗示过,其中一些没有。 这是我试图编译它们的全部内容(带有参考资料),并展示易于阅读的例子,使读者能够select适合自己需求的例子。


示例input树

在下面的例子中,这个结构将被打乱。

 .dotfile dir/ .hidden file.txt root.txt 

POSIX(跨平台,跨壳)解决scheme

正如Phil P. 指出的那样 ,您可以使用pax来代替tar。

平常的行为:

 $ pax -wzvf ../ball.tar.gz . […] $ pax -zf ../ball.tar.gz . ./.dotfile ./dir ./dir/.hidden ./dir/file.txt ./root.txt 

没有点斜线:

 $ pax -wzvf ../ball.tar.gz -s ':^\./::' . […] $ pax -zf ../ball.tar.gz . .dotfile dir dir/.hidden dir/file.txt root.txt 

壳牌Globbing(跨平台)解决scheme

您也可以使用*代替. 正如奥特指出的那样 。 这个解决scheme基本上是chutz 答案的简短forms,因为在将下面的例子中的星号作为parameter passing给tar程序之前,shell会将所有非隐藏文件中的星号扩展。

没有点斜线(但注意缺less的根级.dotfile ):

 $ tar -czvf ../ball.tar.gz * […] $ tar -tzf ../ball.tar.gz dir/ dir/.hidden dir/file.txt root.txt 

如果你不关心在CWD中打包点文件,你就完成了。

如果你照顾,你不是没有追索权。 在许多shell(例如bash )中,通过更改shell选项,可能会在shell glob中包含点文件。 用bash,这是与shopt完成的:

dotglob

如果设置, bash包含以'。'开头的文件名。 在path名扩展的结果中。

 $ shopt -s dotglob # Include dot-files in pathname expansions $ tar -czvf ../ball.tar.gz * […] $ shopt -u dotglob # Restore shell's default globbing behavior $ tar -tzf ../ball.tar.gz .dotfile dir/ dir/.hidden dir/file.txt root.txt 

GNU(Linux)解决scheme

在Jordan Bonitatis的回答中提到使用–xform 。

平常的行为:

 $ tar -czvf ../ball.tar.gz . […] $ tar -tzf ../ball.tar.gz ./ ./root.txt ./.dotfile ./dir/ ./dir/file.txt ./dir/.hidden 

没有点斜线:

 $ tar -czvf ../ball.tar.gz --xform 's:^\./::' . [--show-transformed-names|--show-stored-names] […] $ tar -tzf ../ball.tar.gz ./ root.txt .dotfile dir/ dir/file.txt dir/.hidden 

BSD(Mac OS X)解决scheme

使用-s ,它与pax / sed很相似,但不完全如下所示。

平常的行为:

 $ tar -czvf ../ball.tar.gz . […] $ tar -tzf ../ball.tar.gz ./ ./.dotfile ./dir/ ./root.txt ./dir/.hidden ./dir/file.txt 

没有点斜线:

 $ tar -czvf ../ball.tar.gz -s '/.//' . tar: Removing leading '/' from member names […] $ tar -tzf ../ball.tar.gz .dotfile dir/ root.txt dir/.hidden dir/file.txt 

不知道这是什么版本的tar ,但通常你必须指定你想存档的文件。 像tar c . 压缩本地目录中的所有内容。 在我的机器上运行你的命令我得到:

 tar: Cowardly refusing to create an empty archive 

所以,如果你不想获得领先的./ ,这是你压缩本地目录时得到的. ,你可以直接指定文件。 例如:

 > tar c hosts fstab | tar tv -rw-r--r-- root/root 1225 2012-10-20 13:37 hosts -rw-r--r-- root/root 678 2012-05-13 22:09 fstab 

我已经使用tar -P来保存前导/ (而不是./ )。但是,这并不完全清楚这是否会帮助你的情况。

 -P, --absolute-names don't strip leading '/'s from file names 

人焦油

在tar的旧版本中,它使用了tar中提供的完整path名,但是这在某种程度上是有问题的,因为可能需要第二个副本,并在旧格式date中无意中扩展tar档案,可能会覆盖现有的一个或多个文件。

因此,在几乎任何Linux发行版中分发的tar二进制文件的最新版本中,都会将./放在每个打包文件的开头,这样,无意的扩展就会将存档扩展到当前工作目录和下面。

我不知道为什么它会给你造成这样的问题。 如果您处于正确的目录级别,那么您希望将该存档扩展到哪里,那么就可以做到这一点。 例如,假设你有一个文件

  /tmp/myarchive.tar 

让我们假设档案的内容是

 ./etc/hosts
 ./etc/profile
 ./etc/passwd
 ./etc/group

如果在当前工作目录为/(即根目录)的情况下展开此存档,则这些文件将覆盖现有的文件

 / etc / hosts文件
 / etc / profile文件
 / etc / passwd文件
的/ etc /组

如果这是你想要的,你已经明白了。 但是,让我们说,你只是想从这个档案中的主机文件,但突然之间,你删除configuration文件密码和组文件。 希望你有一个好的备份在这一点上,以便你可以得到他们回来

但是,如果您是系统pipe理员,避免处于根级别,除非他/她故意需要,您很可能已经login到位于/ home / some-user下的ans,或者如果您以root身份login,在/根目录下。 让我们说你在/根。 当你执行命令

 #tar -xvf /tmp/myarchive.tar

你会结束

 /根/ etc / hosts中
 /根/ etc / profile中
 /根/ etc / passwd中
 /根的/ etc /组

没有伤害,没有犯规。 然后

 #mv / root / etc / hosts / etc / hosts

瞧。 你完成了你的目标。