我尝试创建一个带有参数中的文件或目录的 .tar.gz 来进行备份。
但是,当我创建 .tar.gz 档案时,出现此错误:
tar: path_directory_1: cannot stat: No such file or directory
tar: path_directory_2 : cannot stat: No such file or directory
tar: Stopped with failed status due to previous errors
我如何建立档案:
tar zcvf $dirbackup/backup-$backupDate.tar.gz $string
哪里string
:
old_IFS=$IFS
IFS=$'\n'
string="";
for line in $(cat $1); do
string="$string $line"
done
IFS=$old_IFS
$1
:包含要保存的路径目录和路径文件的文件。
内容示例$1
(仅要保存的目录路径):
~/Documents/MIAGE/L3/semestre5/web
~/Documents/MIAGE/L3/semestre5/communication/
使用 set -x 的结果:
+ tar zcvf /var/backups/mesbackups/backup-09-11-2016-13-58/backup-09-11-2016-13-58.tar.gz '~/Documents/MIAGE/L3/semestre5/web' '~/Documents/MIAGE/L3/semestre5/communication/'
tar: ~/Documents/MIAGE/L3/semestre5/web : cannot stat : No such file or directory
tar: ~/Documents/MIAGE/L3/semestre5/communication : cannot stat : No such file or directory
tar: Stopped with failed status due to previous errors
当我在 shell 中运行这个命令时它起作用了......
tar zcvf /var/backups/mesbackups/test/backup-09-11-2016-13-58.tar.gz ~/Documents/MIAGE/L3/semestre5/web ~/Documents/MIAGE/L3/semestre5/communication/
我该如何处理我的脚本?似乎没有引号也可以工作,不是吗?
答案1
如果$1
是包含要添加到存档的文件列表的文件的名称,每行一个,那么您应该能够使用以下--files-from FILE
形式tar
tar zcvf "$dirbackup"/backup-"$backupDate".tar.gz --files-from "$1"
如果由于某种原因不能使用--files-from
,那么下一个最佳选择可能是使用 bash 数组
mapfile -t files < "$1"
tar zcvf "$dirbackup"/backup-"$backupDate".tar.gz "${files[@]}"
但如果文件数量$1
非常大,这可能会出现问题。
答案2
分析
查看输入文件示例
~/Documents/MIAGE/L3/semestre5/web
~/Documents/MIAGE/L3/semestre5/communication/
以及来自的错误消息tar
tar: ~/Documents/MIAGE/L3/semestre5/web : cannot stat : No such file or directory
tar: ~/Documents/MIAGE/L3/semestre5/communication : cannot stat : No such file or directory
您似乎假定 shell 解释器或将在使用以下任一结构读取其行时tar
扩展波浪符号 ( ):~
for i in $(cat infile)
while read i; do ...; done < infile
mapfile ... < infile
这种假设是错误的。没有一个常见的 shell 解释器能够执行扩张,或者更具体地说波浪号扩展在这些情况下。它只评估转义序列(参见read
)。对我而言,也没有已知的实现tar
执行参数扩展(并且它不应该执行,因为这会产生很多问题)。
解决方案
您需要以某种方式扩展输入文件中的波浪符号。
最简单的方法可能是手动或使用过滤器更改输入文件(如果您可以确定$HOME
不包含sed
转义符或分隔符(此处\
和;
)):
sed -e 's;^~\(\/\|$\);'"$HOME"'\1;' infile | tar cvzf my-archive.tar.gz --from-file -
如果你想利用所有可用的 shell 扩展,并且可以确保输入正确转义您可以使用eval
内置命令:
while read -r i; do
eval echo "$i"
done < infile |
tar cvzf my-archive.tar.gz --from-file -