关于Linux:tar目录,但不要在存档中存储完全绝对路径

Tar a directory, but don't store full absolute paths in the archive

在备份shell脚本中,我有以下命令:

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

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

1
2
3
4
5
6
7
8
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。不知道,万一我把备份的网站提取到一个Web数据不存储在/var/www下的地方。

对于上面的示例,我希望:

1
2
3
4
5
6
7
8
tar -tf site1.bz2
style.css
index.html
page2.html
page3.html
images/img1.png
images/img2.png
subdir/index.html

所以,当我提取时,文件是在当前目录中提取的,之后我不需要移动提取的文件,这样子目录结构就得以保留。

stackoverflow和网络上的其他地方已经有很多关于tar和backuping的问题,但大多数都要求删除整个子目录结构(扁平化),或者只添加或删除名字的首字母/in(我不知道提取时它会发生什么变化),但不会有更多的问题。

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

1
2
3
4
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的工作原理?


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

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

来自man tar

1
2
3
4
OTHER OPTIONS

  -C, --directory DIR
       change to directory DIR


选项-C起作用;为了澄清,我将发布两个示例:

  • 创建一个没有完整路径的tarball:完整路径/home/testuser/workspace/project/application.war,我们只需要project/application.war,所以:

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

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

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

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

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

    /home/deploy号:提取物project:关于创建tarball

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

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


    似乎到tar 2.8.3版的-C选项并不能在所有平台(OSE)上持续工作。据说-C选项将目录添加到存档中,但在mac和ubuntu上,它将绝对路径前缀添加到生成的tar.gz文件中。

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

    因此,一致而健壮的解决方案是将cd导入到source_path(source_dir的父目录)并运行

    1
    tar target_path/file.tar.gz source_dir

    1
    tar -cf target_path/file.tar.gz source_dir

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


    以下命令将创建根目录".",并将指定目录中的所有文件放入该目录。

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

    如果您想将所有文件放在tar文件的根目录中,@chinthaka是对的。只需CD进入目录,然后执行以下操作:

    1
    tar -cjf target_path/file.tar.gz *

    这将把CWD中的所有文件作为根文件放到tar文件中。


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

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

    使用"point"可以创建一个名为"point"的文件夹(在Ubuntu16上)。

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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/
    /