rm 命令可以在删除所有文件之前在 bash 脚本中完成吗?

fla*_*ash 7 linux bash mount

我编写了一个简单的 bash 脚本来每天将某些文件备份到备份装载并保留最近 3 天的备份。这显然太简单了,因为我偶尔会遇到奇怪的行为,这可以通过在 rm 完成之前执行第一个 mv 来解释。

这是脚本:

#!/bin/bash

mount /mnt/backups

while [ ! -d /mnt/backups/dailyBackup-0 ]
do
        echo "Backup mount not present, sleeping..."
        sleep 30
done

rm -r /mnt/backups/dailyBackup-2
mv /mnt/backups/dailyBackup-1 /mnt/backups/dailyBackup-2
mv /mnt/backups/dailyBackup-0 /mnt/backups/dailyBackup-1

dirname="/mnt/backups/dailyBackup-0"
mkdir $dirname

cd /
rsync -qr --stats root etc var $dirname

umount /mnt/backups
Run Code Online (Sandbox Code Playgroud)

虽然这在很多时候都很好,但有时我会得到以下结果,看起来dailyBackup-1 在dailyBackup-2 完成删除之前被移动了。如果这是正在发生的事情,预防它的最佳方法是什么?

/mnt/backups/dailyBackup-0:
total 0
drwxrwxrwx 1 root root 0 2010-12-07 03:27 var
drwxrwxrwx 1 root root 0 2010-12-07 02:39 root
drwxrwxrwx 1 root root 0 2010-12-07 02:38 etc

/mnt/backups/dailyBackup-1:
total 0
drwxrwxrwx 1 root root 0 2010-12-06 03:26 var
drwxrwxrwx 1 root root 0 2010-12-06 02:32 root
drwxrwxrwx 1 root root 0 2010-12-06 02:32 etc

/mnt/backups/dailyBackup-2:
total 0
drwxrwxrwx 1 root root 0 2010-12-07 02:36 var
drwxrwxrwx 1 root root 0 2010-12-05 03:21 dailyBackup-1
Run Code Online (Sandbox Code Playgroud)

小智 11

问题很可能是 rm失败,请注意,dailyBackup-2 中的 var 仍然存在,很可能是因为其中的某些文件无法删除。

作为关于编写系统管理 shell 脚本的一般说明:

a) 始终确保检查脚本的(错误)输出,除非您的电子邮件设置已损坏,否则您将通过来自 cronjobs 的邮件自动收到它

b) 始终确保处理可能发生的任何和所有错误(例如,rm 或 mv 失败)将 set -e 放在脚本顶部是个好主意,这将使 shell 在遇到第一个未处理的错误时退出错误(用于调试,还添加 set -x,它将打印正在执行的所有命令,以便您可以查看脚本在做什么)

并回答您的原始问题: rm 永远不会在删除所有文件之前退出,或者更准确地说,在 unlink() 系统调用它找到的最后一个文件完成之前。(我能想象的唯一一种情况是,在取消链接后文件可能仍然存在的地方可能是一些晦涩的错误网络文件系统......)但是 rm 退出并不意味着所有文件都已成功删除(即使您是 root 用户并且正在使用 -fr (您甚至没有使用 -f)),例如,如果文件在 ext* 文件系统上被标记为不可变,或者文件是在 rm 遍历树时新创建的。rm 将报告错误消息和不成功的返回统计信息


Jan*_*nen 5

尝试改变这个

rm -r /mnt/backups/dailyBackup-2
mv /mnt/backups/dailyBackup-1 /mnt/backups/dailyBackup-2
mv /mnt/backups/dailyBackup-0 /mnt/backups/dailyBackup-1
Run Code Online (Sandbox Code Playgroud)

作为

rm -r /mnt/backups/dailyBackup-2 &&
mv /mnt/backups/dailyBackup-1 /mnt/backups/dailyBackup-2 &&
mv /mnt/backups/dailyBackup-0 /mnt/backups/dailyBackup-1 &&
Run Code Online (Sandbox Code Playgroud)

因此,只有在前一个命令成功完成(或者,换句话说,以状态 0 退出)时,才会运行每个命令。