被bash脚本意外删除数据库,请营救
我的开发人员犯了一个巨大的错误,我们在服务器上找不到我们的mongo数据库。请救救我 他登录到服务器,并将以下shell保存在被bash脚本意外删除数据库,请营救,bash,filesystems,ubuntu-14.04,data-recovery,disaster-recovery,Bash,Filesystems,Ubuntu 14.04,Data Recovery,Disaster Recovery,我的开发人员犯了一个巨大的错误,我们在服务器上找不到我们的mongo数据库。请救救我 他登录到服务器,并将以下shell保存在~/crontab/mongod\u back.sh下: 然后他运行/mongod\u back.sh,然后有很多权限被拒绝,然后他执行了Ctrl+C。然后服务器自动关闭 他试图重新启动服务器,但出现grub错误: 然后他联系了阿里云,工程师将磁盘连接到另一台工作的服务器,以便检查磁盘。然后,他意识到一些文件夹已经不见了,包括/data/mongodb所在的位置 1)
~/crontab/mongod\u back.sh
下:
然后他运行/mongod\u back.sh
,然后有很多权限被拒绝
,然后他执行了Ctrl+C
。然后服务器自动关闭
他试图重新启动服务器,但出现grub错误:
然后他联系了阿里云,工程师将磁盘连接到另一台工作的服务器,以便检查磁盘。然后,他意识到一些文件夹已经不见了,包括/data/
mongodb所在的位置强>
1) 我们只是不明白bash如何破坏磁盘,包括/data/
2) 当然,有可能把/data/
拿回来吗
PS:他以前没有拍过磁盘的快照 问题1
1) 我们只是不明白bash如何破坏包括/data/在内的磁盘
原因:$OUT\u DIR
未设置
在bash
和sh
中,注释被写成#comment
,而不是//comment
下面的行将具有以下效果
someVariable=someValue // not a comment
- 将
分配给变量someValue
,但仅分配给该行。在该行之后,变量将返回其旧值,在本例中为空someVariable
- 执行“命令”
,即使用参数//非注释
、非
和a
的程序。由于注释
只是一个目录(与/
相同),这将导致错误消息,仅此而已/
IFS=read-r-line
或LC\u ALL=C sort
查看您的脚本,以下几行可能导致了问题:
OUT_DIR=/data/backup/mongodb/tmp // ...
...
rm -rf $OUT_DIR/*
我很抱歉把这个带给您,但是您基本上执行了rm-rf/*
,因为$OUT\u DIR
扩展为空字符串
对其他系统的潜在风险
即使$OUT\u DIR
不是空的,效果也可能是一样的,因为/
rm后面有一个/
注释。考虑命令
rm -rf some // thing
这将删除三个文件/目录some
,/
和thing
。如前所述,/
与/
是同一个目录
然而,Linux上的大多数rm
实现都有针对这种情况的保护措施,不会如此轻易地删除/
。在Ubuntu上,你会得到以下警告(不要在家里尝试。如果你的rm
不同,这会很糟糕。)
问题2
2) 当然,有可能得到/数据/回来吗
这与StackOverflow无关。然而,你可以找到
您可以尝试一些恢复工具,但如果没有备份,则无法保证您可以恢复数据 在语言之间切换可能很棘手<代码>/不是shell中的注释启动程序,它是
。所有带有这些“注释”的命令都被错误地解析并跳过:
$ VAR=whatever // comment
bash: //: Is a directory
[$?=126]
$ echo "($VAR)"
()
因此,OUT\u DIR=…
被忽略,$OUT\u DIR
为空。很容易猜到是什么
rm -rf $OUT_DIR/*
然后我就去了。基本相当于
rm -rf /*
使用您的备份来还原数据库。我可以读取注释字段中的中文单词,从第10行开始,用户想创建一个临时文件夹,但使用了
cd
,因此如果/data/backup/mongodb/tmp
首先不存在,那么$OUT\u DIR为空或null,在第11行变成rm-rf/*
对不起,它是关于文件系统,而不仅仅是数据库…它与shell相关。我们不明白为什么shell会删除这些文件夹。也许还有其他原因?了解shell是如何删除这些文件夹的将有助于我们恢复它们。@SoftTimur:如果您想要回数据,那么您的位置就错了。如果您想知道代码有什么问题以及如何做得更好,那么你就在这里了。我想这也必须说:认为/
在bash
中引入注释的人没有权利接触生产服务器。我还将在脚本中包括set-u-e
——一旦发生错误或存在未分配的变量时,这将自动退出。。。如果您在bash中使用管道和陷阱,set-Eeuo pipefail
将保持它的安全我尝试执行someVariable=someValue echo“someVariable=$someVariable”
但它只输出someVariable=
。答案是变量赋值只针对那一行。如果这是正确的,为什么我会得到一个空值?@VCD,因为变量在设置之前已展开。Bash分多个步骤处理命令,扩展变量(var
)是第一步,赋值var=…
是后面的步骤——如果是另一种方式,您无法编写类似var=“…$var..”
)的内容。使用var=test Bash-c'echo“$var”
您将获得预期的输出(注意单引号)。吹毛求疵:在rm
的参数中还有另一个/
,因此即使$OUT\u DIR
设置正确,也会是一场灾难,我们希望备份脚本是由其他人编写的。
rm -rf /*