我在备份 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 的工作原理?
-C
只是表示“更改目录”,而替换路径(或前缀)只能由 --transform
完成。里夫superuser.com/questions/595510/prepend-prefix-in-tar/595512 你可以简单的 -C(改变目录)和 --transform 它:``` tar cjf site1.bz2 --transform "s/^\.\//$targetbase/" -C /var/www/site1 . ```
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
选项 -C
有效;只是为了澄清,我将发布 2 个示例:
创建没有完整路径的压缩包:完整路径 /home/testuser/workspace/project/application.war 我们想要的只是 project/application.war 所以: tar -cvf output_filename.tar -C /home/testuser/workspace project 注意:workspace 和 project 之间有一个空格; tar 将用 project 替换完整路径。通过更改目标路径(默认为 .,即当前目录)提取 tarball tar -xvf output_filename.tar -C /home/deploy/ tar 将根据给定路径提取 tarball 并保留创建路径;在我们的示例中,文件 application.war 将被提取到 /home/deploy/project/application.war。 /home/deploy:在提取项目中给出:在创建 tarball 时给出
注意:如果要将创建的 tarball 放在目标目录中,只需在 tarball 名称之前添加目标路径即可。例如:
tar -cvf /path/to/place/output_filename.tar -C /home/testuser/workspace project
似乎 tar v2.8.3 之前的 -C
选项不能在所有平台(操作系统)上始终如一地工作。 -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 文件目录结构中的绝对路径前缀。
tar
之后添加 -cvf
),我发现生成的 tar.gz 文件内部没有绝对路径,这与其他几个答案一致。如果您认为 tar 在我用于测试的两个系统上都已损坏或已过时,请链接到一些支持您答案的文档。我认为 -C
选项在执行之前会更改目录(与其他答案一样)。当我省略它时,tar 会尝试从 ./
添加垃圾,包括从 ./
开始的路径。
cd
。您的回答说该工具的工作方式与文档所说的工作方式以及它在我的系统上的工作方式相反,所以这是一个错误的答案。你可以很容易地修复它。
一个小细节:
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)
ls -A
,您也会获得隐藏文件,而无需尝试遍历 ..
和 .
文件,如果在尝试解析符号链接的地方执行 tar 或 rsync,这是一个常见的混淆来源。
以下命令将创建一个根目录“。”并将指定目录中的所有文件放入其中。
tar -cjf site1.tar.bz2 -C /var/www/site1 .
如果要将所有文件放在 tar 文件的根目录下,@chinthaka 是对的。只需 cd 进入目录并执行以下操作:
tar -cjf target_path/file.tar.gz *
这会将 cwd 中的所有文件作为根文件放入 tar 文件中。
使用“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/
/
.
,即当前目录。在 tar.gz
结构的上下文中,这只是基本/根/顶层,对吗?
如果要归档子目录并修剪子目录路径,此命令将很有用:
tar -cjf site1.bz2 -C /var/www/ site1
发现 tar -cvf site1-$seqNumber.tar -C /var/www/ site1
比 tar -cvf site1-$seqNumber.tar -C /var/www/site1 .
更友好的解决方案(注意第二个解决方案中的 .),原因如下
tar 文件名可能无关紧要,因为原始文件夹现在是存档条目
对内容无关紧要的 tar 文件名现在可以用于其他目的,例如序列号、定期备份等。
tar
归档当前目录中的所有内容。-C
设置当前目录。tar -czvf site1.tar.gz -C /var/www/ site1
(注意空格,我仍在使用 -C 来 cd 到父目录,并指定dir 到 tar 而不是点)./folders
如何删除它?