385

我在备份 shell 脚本的一部分中有以下命令:

tar -cjf site1.bz2 /var/www/site1/

当我列出档案的内容时,我得到:

tar -tf site1.bz2
var/www/site1/style.css
var/www/site1/index.html
var/www/site1/page2.html
var/www/site1/page3.html
var/www/site1/images/img1.png
var/www/site1/images/img2.png
var/www/site1/subdir/index.html

但我想/var/www/site1从存档中的目录和文件名中删除部分,以简化提取并避免无用的常量目录结构。永远不知道,以防万一我将备份的网站提取到网络数据未存储在/var/www.

对于上面的示例,我想要:

tar -tf site1.bz2
style.css
index.html
page2.html
page3.html
images/img1.png
images/img2.png
subdir/index.html

因此,当我提取时,文件被提取到当前目录中,之后我不需要移动提取的文件,因此保留了子目录结构。

在网络上和其他地方已经有很多关于 tar 和备份的问题stackoverflow,但大多数都要求删除整个子目录结构(扁平化),或者只是添加或删除名称中的初始 / (我没有不知道提取时它会发生什么变化),但仅此而已。

在阅读了一些在这里和那里找到的解决方案以及手册之后,我尝试了:

tar -cjf site1.bz2 -C . /var/www/site1/
tar -cjf site1.bz2 -C / /var/www/site1/
tar -cjf site1.bz2 -C /var/www/site1/ /var/www/site1/
tar -cjf site1.bz2 --strip-components=3 /var/www/site1/

但他们都没有按照我想要的方式工作。有些什么都不做,有些则不再归档子目录。

它在由 Cron 启动的备份 shell 脚本中,所以我不太清楚,是哪个用户运行它,路径和当前目录是什么,所以总是需要为所有内容编写绝对路径,并且不希望更改当前目录避免在脚本中进一步破坏某些内容(因为它不仅备份网站,还备份数据库,然后将所有内容发送到 FTP 等)

如何做到这一点?

我是否误解了选项 -C 的工作原理?

4

8 回答 8

512
tar -cjf site1.tar.bz2 -C /var/www/site1 .

在上面的示例中, tar 将/var/www/site1在执行其操作之前更改为目录,因为-C /var/www/site1给出了选项。

来自man tar

OTHER OPTIONS

  -C, --directory DIR
       change to directory DIR
于 2013-09-08T07:49:53.793 回答
54

该选项-C有效;只是为了澄清,我将发布 2 个示例:

  1. 创建没有完整路径的压缩包:完整路径/home/testuser/workspace/project/application.war和我们想要的就是project/application.war这样:

    tar -cvf output_filename.tar  -C /home/testuser/workspace project
    

    workspace注意:和之间有空格project;tar 将用 just 替换完整路径project

  2. 通过更改目标路径提取 tarball(默认为.,即当前目录)

    tar -xvf output_filename.tar -C /home/deploy/
    

    tar将根据给定路径提取 tarball 并保留创建路径;在我们的示例中,文件application.war将被提取到/home/deploy/project/application.war.

    /home/deploy: 在提取
    project时给出 : 在创建 tarball 时给出

注意:如果要将创建的 tarball 放在目标目录中,只需在 tarball 名称之前添加目标路径即可。例如:

tar -cvf /path/to/place/output_filename.tar  -C /home/testuser/workspace project
于 2014-12-03T15:01:22.857 回答
22

似乎-Ctar v2.8.3 之前的选项在所有平台(操作系统)上都无法始终如一地工作。-C据说该选项会将目录添加到存档中,但在 Mac 和 Ubuntu 上,它会在生成的 tar.gz 文件中添加绝对路径前缀。

tar target_path/file.tar.gz -C source_path/source_dir

因此,一致且强大的解决方案是cd进入 source_path(source_dir 的父目录)并运行

tar target_path/file.tar.gz source_dir

或者

tar -cf target_path/file.tar.gz source_dir

在你的脚本中。这将删除生成的 tar.gz 文件目录结构中的绝对路径前缀。

于 2016-02-12T10:18:32.793 回答
10

一个小细节:

tar -cjf site1.tar.bz2 -C /var/www/site1 .

将文件添加为

tar -tf site1.tar.bz2
./style.css
./index.html
./page2.html
./page3.html
./images/img1.png
./images/img2.png
./subdir/index.html

如果你真的想要

tar -tf site1.tar.bz2
style.css
index.html
page2.html
page3.html
images/img1.png
images/img2.png
subdir/index.html

您应该先 cd 进入目录或运行

tar -cjf site1.tar.bz2 -C /var/www/site1 $(ls /var/www/site1)
于 2020-08-24T21:31:57.373 回答
9

以下命令将创建一个根目录“。” 并将指定目录中的所有文件放入其中。

tar -cjf site1.tar.bz2 -C /var/www/site1 .

如果要将所有文件放在 tar 文件的根目录下,@chinthaka 是对的。只需 cd 进入目录并执行以下操作:

tar -cjf target_path/file.tar.gz *

这会将 cwd 中的所有文件作为根文件放入 tar 文件中。

于 2016-10-05T09:31:32.907 回答
5

使用“point”会导致创建一个名为“point”的文件夹(在 Ubuntu 16 上)。

tar -tf site1.bz2 -C /var/www/site1/ .

我更详细地处理了这个问题并准备了一个例子。多行录音,加上一个例外。

tar -tf site1.bz2\
    -C /var/www/site1/ style.css\
    -C /var/www/site1/ index.html\
    -C /var/www/site1/ page2.html\
    -C /var/www/site1/ page3.html\
    --exclude=images/*.zip\
    -C /var/www/site1/ images/
    -C /var/www/site1/ subdir/
/
于 2018-12-11T19:35:20.153 回答
1

如果要归档子目录并修剪子目录路径,此命令将很有用:

tar -cjf site1.bz2 -C /var/www/ site1
于 2019-01-29T12:14:48.203 回答
0

发现tar -cvf site1-$seqNumber.tar -C /var/www/ site1tar -cvf site1-$seqNumber.tar -C /var/www/site1 . (注意第二个解决方案中的.)更友好的解决方案,原因如下

  • tar 文件名可能无关紧要,因为原始文件夹现在是存档条目
  • 对内容无关紧要的 tar 文件名现在可以用于其他目的,例如序列号、定期备份等。
于 2020-07-07T18:06:32.277 回答