复制所有文件和目录到同一父目录中的另一个目录中(BASH命令)

3

我正在尝试编写一个简单的脚本,将所有位于$HOME目录中的文件和文件夹复制到$HOME/Backup/文件夹中,包括隐藏文件和文件夹,但不包括Backup/文件夹自身。以下是我目前用于复制的代码:

shopt -s dotglob

for file in $HOME/*
do
    cp -r $file $HOME/Backup/
done

Bash告诉我它不能将Backup/复制到自身。然而,当我检查$HOME/Backup/的内容时,发现$HOME/Backup/Backup/存在。
在自身复制Backup/是无用的。如何让bash复制除Backup/之外的所有文件夹?我尝试使用extglob并使用cp -r $HOME/!(Backup)/,但它没有复制我需要的隐藏文件。
4个回答

3
尝试使用rsync。您可以排除文件/目录。
这是一个很好的参考资料。
http://www.maclife.com/article/columns/terminal_101_using_rsync_locally 

我更喜欢完全在bash中完成,但我会查看你提供的链接。 - Hugo

2

Hugo,

像这样的脚本不错,但你可以尝试这个:

cp -r * Backup/; cp -r .* Backup/;

备份时使用的另一个工具是tar。它会压缩您的备份以节省磁盘空间。

还要注意,* 不包括隐藏文件 .。


在所有的文件都复制到备份目录之后,我正在压缩归档文件。我已经使用了 shopt -s dotglob 命令以便 * 可以包含隐藏的点文件。不过我需要一种方法来排除那个目录,因为在备份中拥有备份目录本身的副本是没有用处的。 - Hugo

1
我同意使用rsync会是更好的解决方案,但在bash中跳过一个目录有一种简单的方法:
for file in "$HOME/"*
do
    [[ $file = $HOME/Backup ]] && continue
    cp -r "$file" "$HOME/Backup/"
done

我查了一下你给我的测试&&继续行的语法,看起来应该可以工作,但是bash仍然给出了cp:无法将目录复制到自身中的错误。 - Hugo
尝试在每个cp命令之前打印$file的值,以查看到底是哪个cp参数导致了问题。 - chepner
打印 $file 告诉我它没有跳过 $HOME/Backup。我尝试从双括号改为单括号,并将其作为整个 if 语句 if [ "$file" != "$backupdir" ]; then echo "$file" cp -r "$file" $backupdir fi 它好像根本没有评估 if - Hugo
1
“$backupdir”的确切值是什么?由于这是一个字符串比较,因此$file$backupdir都需要完全相同:相同的目录路径,相同的尾随斜杠(或缺少尾随斜杠)等。两个不同的字符串逻辑上表示相同的路径仍将被视为不同。 - chepner
抱歉回复晚了。问题出在这里,我在$backupdir后面加了一个斜杠“/”。谢谢。 - Hugo

1

这并不是直接回答你的问题(其他答案已经回答了),但当你想使用cp进行备份时,尝试使用cp -ua。它递归目录,复制而不是跟随链接,保留权限,并且只会在源文件比目标文件新时才会复制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接