0

几周前,一位高级团队成员意外删除了一个重要的 oracle 数据库文件 (.dbf)。幸运的是,我们可以使用几天前保存的备份文件来恢复系统。

看到这种情况后,我决定实施一种解决方案,rm在提示符下键入命令时至少进行双重确认。(检查超过rm -i

即使我们rm -i默认使用别名,超级快速的键盘手通常也会像那个成员一样犯错误,包括我在内。

起初,我将(通过使用别名)基本 rm 命令替换为特定的 bash 脚本文件,该文件会打印并多次确认目标是否与 oracle 数据库路径或文件相关。简单来说,该脚本在操作rm之前作为过滤器操作。如果与 oracle 无关,则 rm 会正常运行。

在实现时,我认为大多数功能都运行良好,因为除了一个问题外,我只期望用户提示环境。

如果在其他脚本(提供的 oracle、其他供应商修改 oracle 路径、安装程序等)或程序(通过使用系统调用)中调用 rm 命令。

  1. 我该如何区分这种情况?如果上面提供的脚本遇到修改后的 rm,则该执行将不再继续。

  2. 你有更复杂的方法吗?

我相信大多数读者都能理解我懒惰的解释。如果您无法从上面看到清晰的风景,请告诉我。我会详细说明。

4

4 回答 4

3

我们读到man bash

除非使用 shopt 设置了 expand_aliases shell 选项,否则当 shell 不是交互式时,别名不会展开。

然后,如果您使用aliasmakerm调用您的 shell 脚本,则默认情况下其他脚本不会使用它。如果这是你想要的,那么你就已经安全了。

问题是如果您希望脚本调用您的 rm 版本并在它发生时做一些聪明的事情。Alias 对前者来说是不够的;对于显式rm调用. 对于不是 shell 脚本的程序,系统调用比.$PATH/bin/rmunlinksystem("rm ...")

我认为,为了使整个“安全 rm”变得有用,即使交互调用它也应该避免提示。每个用户都会养成对它说“是”的习惯,并且没有已知的解决方法。可行的方法是将文件移动到回收站而不是删除,从而使损坏易于撤消(我似乎记得,有现成的解决方案)。

于 2013-01-21T13:10:49.327 回答
1

答案在alias手册页中:

          Note  aliases  are  not  expanded  by default in non-interactive
          shell, and it can be enabled by setting the expand_aliases shell
          option using shopt.

自己检查一下man alias;)

不管怎样,我会按照你选择的方式去做

于 2013-01-21T13:03:19.973 回答
0

如果您正在使用bash,您可以导出您的 shell 函数,这也将使其在脚本中可用。

#!/usr/bin/env bash

# Define a replacement for `rm` and export it. 
rm() { echo "PSYCH."; }; export -f rm

Shell 函数优先于内置函数和外部实用程序,因此仅使用rm脚本将调用该函数 - 除非它们通过调用/bin/rm ...或显式绕过该函数command rm ...

将上述内容(使用您的实际实现rm())放在每个用户的~/.bashrc文件中,或者放在系统范围的 bash 配置文件中 - 遗憾的是,它的位置不是标准化的(例如:Ubuntu: /etc/bash.bashrc; Fedora /etc/bashrc

于 2014-07-06T18:36:13.243 回答
0

区分情况:您可以创建一个环境变量 say, APPL,它将设置为 say export APPL="DATABASE。在您的自定义脚本中,仅当is (表示与数据库相关的脚本)rm时才执行双重检查,否则表示调用来自其他脚本。APPLDATABASErm

于 2013-01-21T13:15:33.507 回答