bash 脚本意外删除了数据库,请救援
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/55323391/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Deleted database accidentally by a bash script, rescue please
提问by SoftTimur
My developer committed a huge mistake and we cannot find our mongo database anyone in the server. Rescue please!!!
我的开发人员犯了一个巨大的错误,我们在服务器中找不到任何人的 mongo 数据库。求救!!!
He logged into the server, and saved the following shell under ~/crontab/mongod_back.sh
:
他登录到服务器,并将以下 shell 保存在~/crontab/mongod_back.sh
:
And then he run ./mongod_back.sh
, then there were lots of permission denied
, then he did Ctrl+C
. Then the server shut down automatically.
然后他跑了./mongod_back.sh
,然后有很多,然后他跑permission denied
了Ctrl+C
。然后服务器自动关闭。
He tried to restart the server, then he got an grub error:
他试图重新启动服务器,然后他收到一个 grub 错误:
He then contacted AliCloud, the engineer connected the disk to another working server, so that he could check the disk. Then, he realized that some folders have gone, including /data/
where the mongodb is!!!
随后他联系了阿里云,工程师将磁盘连接到另一台正常工作的服务器,以便他可以检查磁盘。然后,他发现有些文件夹不见了,包括/data/
mongodb在哪里!!!
1) We just don't understand how the bash could destroy the disk including /data/
;
1)我们只是不明白bash如何破坏磁盘,包括/data/
;
2) And of course, is it possible to get the /data/
back?
2)当然,有没有可能/data/
拿回?
PS: he did not take a snapshot of the disk before.
PS:他之前没有对磁盘进行快照。
回答by Socowi
Question 1
问题 1
1) We just don't understand how the bash could destroy the disk including /data/;
1)我们只是不明白bash如何破坏包括/data/在内的磁盘;
Reason: $OUT_DIR
was unset
原因:$OUT_DIR
未设置
In bash
and sh
comments are written as # comment
, not // comment
.
The following line will have the following effects
在bash
和sh
评论被写成# comment
,而不是// comment
。
以下行将产生以下效果
someVariable=someValue // not a comment
- Assign
someValue
to variablesomeVariable
, but only for that one line. After that line the variable will go back to its old value, which is null in this case. - Execute the "command"
// not a comment
, that is the program//
with the parametersnot
,a
, andcomment
. Since//
is just a directory (the same as/
) this will cause an error message and nothing more.
- 分配
someValue
给变量someVariable
,但仅限于那一行。在该行之后,变量将返回其旧值,在本例中为 null。 - 执行“命令”
// not a comment
,也就是该程序//
与参数not
,a
和comment
。由于//
只是一个目录(与 相同/
),这将导致错误消息,仅此而已。
Right now this behavior might seem strange, but you may have already used it in well known idioms like IFS= read -r line
or LC_ALL=C sort
.
现在这种行为可能看起来很奇怪,但您可能已经在众所周知的习语中使用过它,例如IFS= read -r line
或LC_ALL=C sort
。
Looking at your script the following lines probably caused the problem:
查看您的脚本,以下几行可能导致了问题:
OUT_DIR=/data/backup/mongodb/tmp // ...
...
rm -rf $OUT_DIR/*
I'm sorry to bring this to you, but you basically executed rm -rf /*
since $OUT_DIR
expanded to the empty string.
很抱歉把这个带给你,但你基本上执行了rm -rf /*
因为$OUT_DIR
扩展到空字符串。
Potential Risk On Other Systems
其他系统的潜在风险
Even if $OUT_DIR
wasn't empty the effect couldhave been the same since there is a //
"comment" after rm
. Consider the command
即使$OUT_DIR
不为空的效果可能是一样,因为有一个//
“注释”之后rm
。考虑命令
rm -rf some // thing
This is supposed to delete the three files/directories some
, //
, and thing
. As already pointed out //
is the same directory as /
.
这应该删除这三个文件/目录some
,//
和thing
。正如已经指出的那样//
与/
.
However, mostimplementations of rm
on Linux have a guard for this case and won't delete /
so easily. On Ubuntu you will get the following warning (don't try this at home. Would suck if your rm
differs.)
然而,Linux 上的大多数实现rm
都有针对这种情况的保护,不会/
那么容易删除。在 Ubuntu 上,您将收到以下警告(不要在家里尝试。如果您rm
不同,会很糟糕。)
$ rm -rf //
rm: it is dangerous to operate recursively on '//' (same as '/')
rm: use --no-preserve-root to override this failsafe
Question 2
问题2
2) And of cause, is it possible to get the /data/ back?
2)当然,是否有可能取回 /data/ ?
This is off-topic for StackOverflow. However, you can find manyanswerstothisquestiononotherstackexchangesites.
这是 StackOverflow 的题外话。但是,你可以找到很多答案给这个问题上其他stackexchange网站。
There are recovery tools you can try, but there is no guarantee that you can restore your data if you don't have a backup.
您可以尝试使用一些恢复工具,但如果您没有备份,则无法保证您可以恢复数据。
回答by choroba
Switching between languages can be tricky! //
is not a comment starter in shell, it's #
. All the commands with these "comments" were parsed wrongly and skipped:
在语言之间切换可能很棘手!//
不是 shell 中的注释启动器,它是#
. 所有带有这些“注释”的命令都被错误地解析并跳过:
$ VAR=whatever // comment
bash: //: Is a directory
[$?=126]
$ echo "($VAR)"
()
Therefore, OUT_DIR=...
was ignored and $OUT_DIR
was empty. It's easy to guess what
因此,OUT_DIR=...
被忽略并$OUT_DIR
为空。很容易猜到是什么
rm -rf $OUT_DIR/*
then did. It was basically equivalent to
然后做了。它基本上相当于
rm -rf /*
Use your backups to restore the database.
使用您的备份来恢复数据库。
回答by user11275761
I can read the Chinese wordings in comment field, from line 10, the user wants to create a temp folder but used cd
, so if /data/backup/mongodb/tmp
does not exist in the first place, then $OUT_DIR is empty or null, after that line 11 became rm -rf /*
.
我可以在注释字段中读取中文措辞,从第 10 行开始,用户想要创建一个临时文件夹但使用了cd
,因此如果/data/backup/mongodb/tmp
首先不存在,则 $OUT_DIR 为空或 null,在第 11 行变为rm -rf /*
.