2010-03-06 181 views
3

如果应用程序正在运行其使用的其中一个共享库被写入或截断,则应用程序将崩溃。移动文件或使用'rm'批量删除文件不会导致崩溃,因为操作系统(Solaris在这种情况下,但我认为这在Linux和其他* nix上也是如此)足够聪明,不会删除与该文件在任何进程打开的时候。运行shell脚本时,如何防止覆盖或截断文件?

我有一个执行共享库安装的shell脚本。有时,它可能用于重新安装已安装的共享库的版本,而无需首先卸载。由于应用程序可能正在使用已经安装的共享库,因此脚本非常聪明,可以将文件打包或移走(例如,当我们知道没有应用程序时,cron可以清空的“已删除”文件夹将运行),然后再安装新的程序,以免它们被覆盖或截断。

不幸的是,最近一个应用程序在安装后崩溃。巧合?很难说。这里真正的解决方案是切换到一个比旧的巨型shell脚本更强大的安装方法,但在交换机制作之前有一些额外的保护会很好。有没有什么方法可以包装一个shell脚本以防止覆盖或截断文件(并且理想情况下会大声地失败),但仍然允许它们被移动或rm'd?

标准的UNIX文件权限不会做到这一点,因为您无法区分移动/从覆盖/截断中删除。别名可以工作,但我不确定整个命令是否需要别名。我想像truss/strace之类的东西,除非在每个动作之前检查过滤器是否真的这样做。我不需要一个完美的解决方案,甚至可以对付故意恶意的脚本。

+0

不提示这个问题不属于堆栈溢出,但我想你可能会在Serverfault上得到一些有趣的和有用的输入。 – Emily 2010-03-06 21:43:37

+0

是的,我在哪个网站发帖时发生冲突,shell脚本是重叠的网站。我会尝试在那里发帖,谢谢。 – 2010-03-07 01:44:59

回答

2

您可以通过

set noclobber 

防止由cp覆盖等是很难阻止脚本通过I/O重定向覆盖。我的意图是重置PATH,使脚本与PATH一起运行,其中只包含一个条目,一个“有福”的目录,您可以在其中放置您知道安全的命令。例如,这可能意味着您的cp版本始终安排使用--remove-destination选项(可能是GNU-ism)。在任何情况下,您都会安排脚本仅执行来自祝福目录的命令。然后您可以单独审核每个这样的命令。

如果您可以阻止脚本通过绝对路径名执行命令,但我不知道如何执行该操作,那就太好了。如果您在常规目录中进行安装,那么除非您进行大量环回安装以使这些目录可见,否则一个chroot监狱可能无济于事。如果您要安装的目录包含危险的命令,我看不出完全保护自己的方式。

顺便说一句,我试过并没有得知如果install(1)在安装前删除了desitination。这将是学习的火花。

+0

这些都是伟大的建议。我很好奇安装,因为它是脚本使用的实用程序之一。 – 2010-03-06 23:14:23

+0

对于任何后来遇到这种情况的人:事实证明,GNU版本的安装有一个--backup选项,用于对要被覆盖的文件进行“备份”。它可能足够精明,可以将现有文件压缩到备份命名文件而不是复制副本,但我没有检查源代码。 – 2010-03-07 01:46:30

1

我推测Bash脚本?剧本很长吗?如果没有,你可以手动完成:

if [ ! -f /tmp/foo.txt ] #If file does not exist 
then 
    ...code 
fi 

但我认为你想要一种方法来包装脚本。你当然可以使用strace来监视文件写入,但是AFAIK它没有中断它们的功能,除非你设置了某种带有规则的入侵检测系统。

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

0

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