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
- We just don't understand how the bash could destroy the disk including /data/;
原因:$OUT_DIR
未设置
在bash
和sh
中评论写成# comment
,而不是// comment
。
下面一行会有如下效果
someVariable=someValue // not a comment
- 将
someValue
赋值给环境变量someVariable
,但仅限于此命令。在该命令之后 变量将返回到它的旧值,在本例中为空。
- 执行“命令”
// not a comment
,即带有参数not
、a
和comment
的程序//
。由于 //
只是一个目录(与 /
相同),这将导致一条错误消息,仅此而已。
现在这种行为可能看起来很奇怪,但您可能已经在 IFS= read -r line
或 LC_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
- 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 /*
.
我的开发人员犯了一个大错误,我们无法在服务器中找到任何人的 mongo 数据库。求救!!!
他登录了服务器,并在~/crontab/mongod_back.sh
下保存了以下shell:
然后他 运行 ./mongod_back.sh
,然后有很多 permission denied
,然后他 Ctrl+C
。然后服务器自动关闭。
他试图重启服务器,然后他得到一个 grub 错误:
随后他联系了阿里云,工程师将磁盘连接到另一台正常工作的服务器上,以便他检查磁盘。然后,他发现 一些文件夹不见了,包括 /data/
mongodb 所在的文件夹!!!
1) 我们只是不明白 bash 是如何破坏磁盘的,包括 /data/
;
2) 当然,是否有可能取回 /data/
?
PS:他之前没有对磁盘进行快照。
问题 1
- We just don't understand how the bash could destroy the disk including /data/;
原因:$OUT_DIR
未设置
在bash
和sh
中评论写成# comment
,而不是// comment
。
下面一行会有如下效果
someVariable=someValue // not a comment
- 将
someValue
赋值给环境变量someVariable
,但仅限于此命令。在该命令之后 变量将返回到它的旧值,在本例中为空。 - 执行“命令”
// not a comment
,即带有参数not
、a
和comment
的程序//
。由于//
只是一个目录(与/
相同),这将导致一条错误消息,仅此而已。
现在这种行为可能看起来很奇怪,但您可能已经在 IFS= read -r line
或 LC_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
- 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 /*
.