Tar目录,但不在存档中存储完整的绝对路径

时间:2013-09-08 07:43:34

标签: linux bash backup tar

我在备份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

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

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

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

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的工作原理?

9 个答案:

答案 0 :(得分:288)

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

答案 1 :(得分:29)

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

  1. 创建没有完整路径的tarball: 完整路径/home/testuser/workspace/project/application.war以及我们想要的只是project/application.war所以:

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

    注意:workspaceproject之间有一个空格; tar将仅使用project替换完整路径。

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

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

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

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

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

    tar -cvf /path/to/place/output_filename.tar  -C /home/testuser/workspace project
    

答案 2 :(得分:7)

似乎-C选项up to tar 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文件目录结构中的绝对路径前缀。

答案 3 :(得分:5)

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

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

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

tar -cjf target_path/file.tar.gz *

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

答案 4 :(得分:2)

一个小细节:

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

您应该先进入目录或运行

tar -cjf site1.tar.bz2 -C /var/www/site1 $(ls /var/www/site1)

答案 5 :(得分:0)

使用“ 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/
/

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

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

  • Tar文件名可以忽略不计,因为原始文件夹现在是归档条目
  • Tar文件名与内容无关紧要,现在可以将其用于其他目的,例如序列号,定期备份等。

答案 8 :(得分:0)

声誉低下(潜伏了许多年,叹息),所以我无法在线发表评论,但是我发现@laktak的答案是唯一可以在Ubuntu 18.04上使用的答案-使用{{1 }机器上的}导致我想要的所有文件都放在tar.bz2文件内的tar -cjf site1.tar.bz2 -C /var/www/site1 .下,虽然可能可以,但是在解压缩时,存在跨OS行为不一致的风险