Installation 运行shell脚本时,如何保护它不被覆盖或截断文件?

Installation 运行shell脚本时,如何保护它不被覆盖或截断文件?,installation,shell,shared-libraries,nfs,reliability,Installation,Shell,Shared Libraries,Nfs,Reliability,如果应用程序在运行其使用的某个共享库时被写入或截断,则应用程序将崩溃。使用“rm”移动文件或将其整体删除不会导致崩溃,因为操作系统(在本例中为Solaris,但我假设在Linux和其他*nix上也是如此)足够智能,不会在任何进程打开文件时删除与该文件关联的索引节点 我有一个执行共享库安装的shell脚本。有时,它可能用于重新安装已安装的共享库版本,而无需先卸载。由于应用程序可能正在使用已安装的共享库,因此脚本是否足够智能以管理文件或将其移开是很重要的(例如,当我们知道没有应用程序将运行时,cro

如果应用程序在运行其使用的某个共享库时被写入或截断,则应用程序将崩溃。使用“rm”移动文件或将其整体删除不会导致崩溃,因为操作系统(在本例中为Solaris,但我假设在Linux和其他*nix上也是如此)足够智能,不会在任何进程打开文件时删除与该文件关联的索引节点

我有一个执行共享库安装的shell脚本。有时,它可能用于重新安装已安装的共享库版本,而无需先卸载。由于应用程序可能正在使用已安装的共享库,因此脚本是否足够智能以管理文件或将其移开是很重要的(例如,当我们知道没有应用程序将运行时,cron可能会清空“已删除”文件夹)在安装新文件之前,请确保它们不会被覆盖或截断

不幸的是,最近一个应用程序在安装后崩溃。巧合很难说。这里真正的解决方案是切换到比旧的巨型shell脚本更健壮的安装方法,但是在切换之前最好有一些额外的保护。有没有办法包装一个shell脚本来保护它不被覆盖或截断文件(理想情况下是失败的),但仍然允许移动或删除它们


标准UNIX文件权限不会起作用,因为您无法区分移动/删除和覆盖/截断。别名可以工作,但我不确定哪些命令需要使用别名。我想象一些类似truss/strace的东西,除了在每个动作之前,它会根据过滤器检查是否真的这样做。我不需要一个完美的解决方案,即使是针对故意恶意脚本也能奏效。

我想是Bash脚本吧?剧本很长吗?如果没有,您可以手动执行此操作:

if [ ! -f /tmp/foo.txt ] #If file does not exist
then
    ...code
fi
但我认为你是在寻求一种方法来把这个故事包装在剧本中。您当然可以使用strace监视文件写入,但它没有中断文件写入的功能,除非您使用规则等设置某种入侵检测系统


但老实说,除非它是一个巨大的脚本,否则这可能比它的价值更麻烦。

您可以通过

set noclobber
通过
cp
等防止覆盖更难。我倾向于重置
路径
,让脚本在
路径
只包含一个条目的情况下运行,这是一个“受祝福的”目录,您可以在其中放置安全的命令。例如,这可能意味着您的
cp
版本总是安排使用
--remove destination
选项(可能是GNU ism)。在任何情况下,您都可以安排脚本只执行目录中的命令。然后,您可以单独检查每个这样的命令

如果您可以阻止脚本按绝对路径名执行命令,这将是一件好事,但我不知道如何做到这一点。如果您在常规目录中进行安装,那么
chroot
jail可能没有帮助,除非您进行大量的环回装载以使这些目录可见。如果你要安装的目录包含危险的命令,我不知道你如何才能完全保护自己不受这些命令的影响


顺便说一句,我试图了解
install(1)
是否在安装之前删除了该选项,但失败了。这将是一个需要学习的过程。

编写您自己的safe_install()函数,并确保它们是唯一使用的方法。如果确实需要确定,请运行两个进程。一个脚本有权进行更改,另一个脚本会提前放弃所有权限,并告诉另一个脚本执行实际的磁盘工作。

不建议这个问题不属于堆栈溢出问题,但我认为您可能会在Serverfault上得到一些有趣和有用的信息。是的,我在哪个站点发布它时遇到了冲突,shell脚本是一个重叠的站点。我会尝试在那里交叉张贴,谢谢。这两个都是很好的建议。我对install也很好奇,因为它是脚本使用的实用程序之一。对于后来遇到这个问题的人来说:事实证明,install的GNU版本有一个--backup选项,它可以“备份”即将被覆盖的文件。它可能足够精明,可以将现有文件mv到备份命名文件,而不是制作副本,但我还没有检查源代码以确定。