bash 脚本意外删除了数据库,求救

Deleted database accidentally by a bash script, rescue please

我的开发人员犯了一个大错误,我们无法在服务器中找到任何人的 mongo 数据库。求救!!!

他登录了服务器,并在~/crontab/mongod_back.sh下保存了以下shell:

然后他 运行 ./mongod_back.sh,然后有很多 permission denied,然后他 Ctrl+C。然后服务器自动关闭。

他试图重启服务器,然后他得到一个 grub 错误:

随后他联系了阿里云,工程师将磁盘连接到另一台正常工作的服务器上,以便他检查磁盘。然后,他发现 一些文件夹不见了,包括 /data/ mongodb 所在的文件夹!!!

1) 我们只是不明白 bash 是如何破坏磁盘的,包括 /data/;

2) 当然,是否有可能取回 /data/

PS:他之前没有对磁盘进行快照。

问题 1

  1. We just don't understand how the bash could destroy the disk including /data/;

原因:$OUT_DIR 未设置

bashsh中评论写成# comment,而不是// comment
下面一行会有如下效果

someVariable=someValue // not a comment
  • someValue赋值给环境变量someVariable,但仅限于此命令。在该命令之后 变量将返回到它的旧值,在本例中为空。
  • 执行“命令”// not a comment,即带有参数notacomment的程序//。由于 // 只是一个目录(与 / 相同),这将导致一条错误消息,仅此而已。

现在这种行为可能看起来很奇怪,但您可能已经在 IFS= read -r lineLC_ALL=C sort.

等众所周知的习语中使用过它

查看您的脚本,以下几行可能导致了问题:

OUT_DIR=/data/backup/mongodb/tmp // ...
...
rm -rf $OUT_DIR/*

很抱歉给你带来这个,但你基本上执行了 rm -rf /*,因为 $OUT_DIR 扩展为空字符串。

其他系统的潜在风险

即使 $OUT_DIR 不为空,效果 也可能 是一样的,因为在 [=34= 之后有一个 // “注释” ].考虑命令

rm -rf some // thing

这应该删除三个 files/directories some//thing。正如已经指出的那样 ///.

是同一个目录

然而,大多数 rm 在 Linux 上的实现对这种情况有保护措施,不会轻易删除 /。在 Ubuntu 上,您将收到以下警告(不要在家尝试此操作。如果您的 rm 不同,那就糟了。

$ rm -rf //
rm: it is dangerous to operate recursively on '//' (same as '/')
rm: use --no-preserve-root to override this failsafe

问题 2

  1. And of cause, is it possible to get the /data/ back?

这与 Whosebug 无关。但是,您可以找到 many answers to this question on other stackexchange sites.

您可以尝试使用恢复工具,但如果没有备份,无法保证您可以恢复数据。

在语言之间切换可能很棘手! // 不是 shell 中的评论起始者,而是 #。所有带有这些 "comments" 的命令都被错误地解析并被跳过:

$ VAR=whatever // comment
bash: //: Is a directory
[$?=126]
$ echo "($VAR)"
()

因此,OUT_DIR=...被忽略,$OUT_DIR为空。很容易猜到什么

rm -rf $OUT_DIR/*

然后做了。基本上等同于

rm -rf /*

使用您的备份恢复数据库。

我能看懂评论区的中文,从第10行开始,用户想创建一个临时文件夹但是用了cd,所以如果/data/backup/mongodb/tmp一开始就不存在,然后 $OUT_DIR 为空或 null,之后第 11 行变为 rm -rf /*.