如果应用程序正在运行其使用的共享库之一被写入或截断,则应用程序将崩溃。 移动文件或使用'rm'批量删除文件不会导致崩溃,因为操作系统(Solaris在这种情况下,但我认为这在Linux和其他* nix上也是如此)足够聪明,不会删除与该文件,而任何进程打开。
我有一个执行共享库安装的shell脚本。 有时,可能会用它来重新安装已经安装的共享库的版本,而无需首先卸载。 因为应用程序可能正在使用已经安装的共享库,所以重要的是脚本足够聪明,可以将文件打包或移动(例如,当我们知道没有应用程序时,cron可以清空的“已删除”文件夹将会运行),然后再安装新的程序,以免被覆盖或截断。
不幸的是,最近一个应用程序在安装后崩溃。 巧合? 很难说。 这里真正的解决scheme是切换到一个更老的安装方法,而不是一个旧的巨大的shell脚本,但它会很高兴有一些额外的保护,直到开关制成。 有没有什么方法来包装一个shell脚本,以防止覆盖或截断文件(理想情况下大声失败),但仍然允许他们移动或rm'd?
标准的UNIX文件权限不会执行这个技巧,因为你无法区分移动/删除和覆盖/截断。 别名可以工作,但我不知道什么样的命令需要别名。 我想像truss / strace之类的东西,除非在每个动作之前检查filter是否真正做到这一点。 我不需要一个完美的解决scheme,甚至可以对付有意识的恶意脚本。
我到目前为止的想法是:
使用install
实用程序 – 这就是它的用途。
在安装软件时,特别是在安装现有软件时,正常的安全操作模式是(或者我的意思是'应该'):
如果在复制东西时出现问题,则不会损坏现有的安装。 这当然假设你有足够的磁盘空间 – 但是磁盘很便宜。
如果你正在编写你自己的安装程序,你可以做类似的事情。 如果你正在使用其他人的安装程序,你将很难处理他们的怪癖。 最终,你需要向供应商投诉。 但是请注意,如果您尝试摆弄标准命令,这些更改可能会回来并咬你。
我的第一个想法是在〜/ .bashrc中build议'设置noclobber'。
第二个想法:Solaris有lsof,fuser或fstat吗? 这些可以检查是否有另一个进程打开文件。
你也可以尝试这样的事情:
safecp() { source=$1 dest=$2 dest_dir=$(dirname dest) [ -d $dest_dir] || mkdir $dest_dir/temp && mv $dest $dest_dir/temp && cp $source $temp }
我认为rsync可能是这个工具。 您可能需要结合干运行或逐项更改来满足您的确切要求。 --ignore-existing
开关也可能是有趣的。
另一件需要考虑的事情是跨文件系统边界使用“cp”会将数据写入当前inode,而同一文件系统中的cp将从旧文件中断开并链接到新文件。