被bash脚本意外删除数据库,请营救

被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)

我的开发人员犯了一个巨大的错误,我们在服务器上找不到我们的mongo数据库。请救救我

他登录到服务器,并将以下shell保存在
~/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 /*