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


我写了一个简单的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

虽然这很好但很多时候,我有时会得到以下内容,看起来像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

7
2017-12-16 11:37






答案:


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

作为编写系统管理shellcript的一般说明:

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

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

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


10
2017-12-16 12:11



感谢您的解释和提示。我将查看错误输出。 - flash
生产脚本中-e标志的+1。好决定。 - pboin
只是为了更新:优秀的建议 - 我真的没有从中捕获错误,现在我可以看到是的,rm有时失败,所以我现在知道要调查什么。 - flash


尝试改变这个

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

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

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


5
2017-12-16 11:58





是通过nfs mount访问的另一台服务器上的文件吗?如果使用软安装设置NFS,则不保证操作将完成。


1
2017-12-16 15:36