我希望备份位于我的主目录中的一些文件。那是
- 我家根目录下的简单文件
- 以及我家中的一些目录,列在 ~/worthaving.txt 中
示例 worthaving.txt:
cloud
work/web
work/python
我做了这个脚本:
#!/bin/bash
srce=/home/poor
dest=/run/media/poor/backup
mkdir -p $dest
cp -v $srce/* $dest/ # simple files
while IFS= read -r worth
do
mkdir -p $dest/$worth
cp -Rv $srce/$worth $dest/$worth # dirs that matters
done < "$srce/worthsaving.txt"
但我最终不仅得到了我想要的东西,而且得到了我的整个家,位于poor
备份根目录下的目录中。
怎么了 ?
答案1
要备份的文件列表中有一个空行。在循环内部,这意味着它$worth
是空的,这又会导致执行以下命令:
cp -Rv /home/poor /run/media/poor/backup/
如果还不清楚,这会将整个主目录复制到poor
目标中的目标目录。
以下是您的循环正确的样子:
while IFS= read -r worth
do
if [ -n "$worth" ] && [ -d "$worth" ]
then
mkdir -p "$dest/$worth"
cp -Rv "$srce/$worth" "$dest/$worth" # dirs that matters
fi
done < "$srce/worthsaving.txt"
尽管正如评论中所暗示的那样,您可以将所有这些替换为rsync
:
rsync -rtR --files-from "$srce/worthsaving.txt" "$srce/" "$dest/"
就我个人而言,我会使用-a
( --archive
) 而不是-rt
( --recursive --times
),但由于您没有使用,cp -a
所以我也坚持使用最小推荐标志rsync
。
作为旁白,总是使用变量时用双引号* 。这可以保护它们免受 shell 的分词和通配符作用。作为示例,考虑my bin
循环分配给 的目录$worth
。如果没有双引号,这将导致以下错误且意外的命令:
cp -Rv /home/poor/my bin /run/media/poor/backup/my bin
这里,将尝试将三个文件或目录(/home/poor/my
,bin
从当前目录, 和/run/media/poor/backup/my
)复制到目标目录bin
* 至少,始终如此,直到您明白为什么您可能在特定情况下不这样做。即便如此,也要重新考虑一下。