甚至在遇到语句删除自己之后,bash脚本如何执行? 对于例如,当我跑test.sh脚本conains:自我删除bash脚本
<--some commands-->
rm test.sh
<--some more commands-->
end
脚本执行到最后删除本身
甚至在遇到语句删除自己之后,bash脚本如何执行? 对于例如,当我跑test.sh脚本conains:自我删除bash脚本
<--some commands-->
rm test.sh
<--some more commands-->
end
脚本执行到最后删除本身
实际发生的是,庆典保持文件打开和rm
不会犯停止。
因此rm
调用libc函数“unlink()”,它将从它所在的目录中删除inode的“链接”。该“链接”实际上是一个文件名以及一个inode号码(可以看到inode数字为ls -i
)。
只要程序打开它,inode就会存在。
您可以轻松地测试这一要求如下:
$ echo read a> ni
$ bash ni
而在另一个窗口:
$ pgrep -lf bash\ ni
31662 bash ni
$ lsof -p 31662|grep ni
bash 31662 wmertens 255r REG 14,2 7 12074052 /Users/wmertens/ni
$ rm ni
$ lsof -p 31662|grep ni
bash 31662 wmertens 255r REG 14,2 7 12074052 /Users/wmertens/ni
即使你不再能看到它在LS文件仍然打开。 所以这并不是说bash会读取整个文件 - 只有bash完成后才能真正完成。
这就是为什么更新程序不应该更改现有的可执行文件,而是取消它们之间的链接,然后重写新版本。 – curiousguy
好的,但如果文件被另一个进程覆盖会发生什么?该文件未链接,因此它被视为“自由空间”,不是吗? –
@G_G覆盖仅表示由文件名命名的目录条目现在链接到另一个inode。只要原始inode没有被bash关闭,它就会存在并将被bash使用。 – w00t
其实之前,这种现象是特定的壳(如bash)的,其阅读将文件存入内存然后执行它们。
如果执行以下a.bat: 呼应YO1 德尔a.bat 回声YO2
会得到以下的输出: C:> a.bat
C:>回声YO1 Yo1
C:> del a.bat 无法找到批处理文件。
这是按照您的期望:-)
这是错误的; w00t的回答是正确的。当bash脚本在运行时,我亲眼看到了错误结果,表示该文件正在被打开并被读取。 –
执行应用程序时,其代码被加载到内存中。您只是删除了磁盘上的文件,这不会影响内存中的代码。 –
假定整个脚本在执行时被读入内存,所以'rm test.sh'后面的命令仍然存在于内存中以便执行。 – MrMisterMan
它不会在内存中创建副本。所以,例如,如果脚本在运行时被修改,它将执行修改。最近这让我很头疼。可爱的例子:这一行脚本会在短时间内填满你的磁盘:'cat $ 0 >> $ 0'。 – Ned