在脚本运行时更新脚本文件,日本惠普误删77TB重要数据

@Ta 01-09 04:47发布,01-09 05:00修改 838点击

转自 https://xw.qq.com/cmsid/20211230A00L9I00?f=newdc

日本惠普公司误删京都大学超算系统77TB重要数据

作者:环球Tech

据京都大学主页的公报显示,本次数据丢失事件发生在 12 月 14 日 到 12 月 16 日之间,一共删除了/LARGE0 目录下的 3400 多万个文件,总容量大约 77 TB,其中有 49 TB 数据可以从备份恢复,28 TB 数据完全丢失。

具体事故的原因日本惠普也在 声明 PDF 中做了详细说明。

惠普用于超算系统的备份脚本会使用 find 命令找出无用的 Log 文件并删除,最近日本惠普为了提高程序的“可读性”对传给 find 命令的变量名做了一些修改,然后更新了系统中的脚本,但是没考虑到 Bash 会在运行过程中实时读取脚本文件然后执行,于是尚在执行中的备份程序读取了新脚本中的 find 指令,最终导致误删文件。

惠普日本在“谢罪声明”中表示对此次事件负全责,并承诺赔偿和善后。

编者记: Bash 在解析 Shell 脚本时,是边解析边执行的,并不是将脚本一次性读入内存后执行。如果脚本在执行时,我们用新脚本覆盖了旧脚本,而且文件的 inode 没有发生变化(比如使用 cp new.sh old.sh,old.sh 内容变了,但 inode 不会变),那么 Bash 就会解析更新后的内容并执行。


老虎会游泳:在脚本运行时直接修改脚本文件,后果难以预料。

最好的情况是,修改后bash读取到的命令不合法,脚本报错退出。

但也有可能读取到的命令恰好合法,但传给命令的参数(变量)未正确设置(比如为旧脚本的值,或者旧脚本未设置该变量,值为空),此时会发生什么就完全不能预料了。

比如,日本惠普遇到的问题就是修改脚本后,正在运行的bash恰好读取到了find命令,但传给命令的路径参数为空(因为旧脚本没有设置对应变量),于是find列出了工作目录中的所有文件,然后这些文件被紧随其后的rm等命令删除。

回复列表(22)
  • @Ta / 01-10 18:20
  • @Ta / 01-09 09:41
    又一个大瓜
  • @Ta / 01-10 08:26
    我居然一直以为惠普是美国的。
    还有老虎为什么可以回复空信息?
  • @Ta / 01-10 11:39
    老老虎威武
  • -
    @Ta / 01-10 16:00
    @老虎会游泳,你的回复是空白的,谷歌浏览器和其他浏览器查看。
    Screenshot_20220110-154230.png
  • @Ta / 01-10 15:50

    @-,它本来就是空白的。

  • -
    @Ta / 01-10 15:51
    @老虎会游泳,那发一个空白的回复表达的是什么?
  • @Ta / 01-10 15:55

    @-,占楼备用。

  • @Ta / 01-10 17:10
    @希望自己长胖胖,惠普就是美国的呀,日本惠普不等于日本的惠普
  • @Ta / 01-10 18:24
  • @Ta / 01-10 17:45
    如何避免
  • @Ta / 01-10 18:07
    @别人,老虎已经修复这个BUG了。
  • @Ta / 01-10 18:18

    @别人@biuaxia,现在想要得到空白内容,需要先发一个非空白内容,然后修改回复,把内容删掉。我只是阻止发言时发出空白内容,因为有个网页插件有Bug,不断自动发空白内容,导致我不得不加以限制。

  • @Ta / 01-10 18:22
  • @Ta / 01-10 18:22
    被锁定
    层主 @老虎会漩泳 于 2022-01-10 18:22 删除了该楼层。
  • @Ta / 01-10 18:34

    @残缘,有三个方法:

    1. 先删后改。因为my.shbash打开,所以rm my.sh并不会真正删除文件,只是把它隐藏了起来,bash依然可以读取它。此后创建的新文件my.shbash正在读取的不是同一个文件。包管理器(比如dpkg)更新软件包时应该都采用了先删后改的流程,你会看到xxx.new被创建,然后再被重命名成旧文件。
    wget -O my.sh.new https://xxx.cn/my.sh
    rm my.sh
    mv my.sh.new my.sh
    
    1. 每次都使用不同的文件名,或者不同的目录,把版本号加在文件名里面。只要不涉及文件替换,就不会有此类问题。

    2. 先停止正在运行的进程,再修改。有风险,很可能会忘记停止,或者以为停止了但是由于某些原因未能停止。

  • @Ta / 01-10 18:39

    @残缘,方法1应该也可以简化成一次mv操作。在原文件存在时,mv应该就是先删除原文件再重命名。

    wget -O my.sh.new https://xxx.cn/my.sh
    mv my.sh.new my.sh
    

    演示,注意文件的Inode

    图片.png
  • @Ta / 01-11 09:12
    @老虎会游泳,学习了
  • @Ta / 01-11 09:26

    喜闻乐见
    http://www.1kmb.com

添加新回复
回复需要登录