几周前,一位资深团队成员意外删除了一个重要的oracle数据库文件(.dbf)。幸运的是,我们可以使用几天前保存的备份文件来恢复系统。
在看到这种情况后,我决定实施一个解决方案,在提示符上输入rm
命令时至少进行双重确认。 (检查超过rm -i
)
即使我们将rm -i
作为默认别名,超级快速的键盘手通常也会犯这样的错误,包括我。
首先,我将(通过使用别名)基本rm命令替换为特定的bash脚本文件,如果目标在oracle数据库路径或文件上相关,则会多次打印并确认。 简单来说,脚本在操作rm之前作为过滤器运行。如果它与oracle无关,则rm将正常运行。
在实施过程中,我认为大多数功能都运行良好,因为除了一个问题,我只期待用户提示环境。
如果在其他脚本(提供oracle,其他供应商修改oracle路径,安装程序等)或程序(通过使用系统调用)中调用rm命令。
我如何区分这种情况? 如果上面提供的脚本遇到了修改后的rm,则该执行不再继续。
你有更复杂的方法吗?
我相信大多数读者都能理解我的懒惰解释。 如果你无法从上面看到清晰的风景,请告诉我。我会详细说明。
答案 0 :(得分:3)
我们在man bash
阅读:
当shell不是交互式时,不会扩展别名,除非 expand_aliases shell选项使用shopt设置。
然后,如果使用alias
使rm
调用shell脚本,则默认情况下其他脚本不会使用它。如果这是你想要的,那么你已经安全了。
问题是,如果你希望你的rm版本被脚本调用,并在它发生时做一些聪明的事情。别名对前者来说是不够的;甚至将rm
放在$PATH
下的某个地方对于明确调用/bin/rm
的程序来说还不够。对于非shell脚本的程序,unlink
系统调用比system("rm ...")
更有可能被使用。
我认为,对于整个“安全的”有用的东西,它应该避免提示,即使在交互式调用时。每个用户都会养成对它说“是”的习惯,并且没有已知的方法。可能有用的是将文件移动到回收站而不是删除,使损坏容易撤消(我似乎记得,已经准备好使用解决方案)。
答案 1 :(得分: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
;)
无论如何,我会以你选择的方式做到这一点
答案 2 :(得分:0)
区分情况:您可以创建一个env变量,例如APPL
,它将设置为export APPL="DATABASE
。在您自定义的rm
脚本中,仅当APPL
为DATABASE
(表示与数据库相关的脚本)时才执行双重检查,否则表示rm
来自{{1}}其他脚本。
答案 3 :(得分: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 ...
显式绕过函数。 / p>
将上面的内容(以及rm()
的实际实现)放在每个用户的~/.bashrc
文件中,或放在系统范围的bash配置文件中 - 遗憾的是,它的位置不是标准化的(例如:Ubuntu: /etc/bash.bashrc
; Fedora /etc/bashrc
)