在类Unix操作系统上,如果文件仍处于打开状态,则可以删除该文件.文件名将不再存在,但数据本身仍然存在,并且任何具有打开句柄的程序(包括bash)都可以继续使用该句柄读取(甚至写入).只有当最后一个程序关闭其句柄时,该文件才会被删除.
因此,从某种意义上说,是的,shell脚本可以自行删除,但在脚本执行完成之后才会真正删除它.
请注意,如果覆盖文件而不是删除文件,则会得到不同的结果.shell可以(并且确实)使用缓冲来避免一次读取一个字节,但缓冲区的大小有限.如果文件内容超出了shell已经读入内存的范围,它将看到新内容.如果检查系统的缓冲区大小,可以创建一个简单的示例.在我的系统上,恰好是8 KiB.所以包含的shell脚本
echo line 1 >test.sh # (8167 random characters) echo line 4
所以第二块数据是" cho line 4
",在我的系统上,输出
$ bash test.sh line 1 test.sh: line 4: e: command not found
因为e
已经读取了,并且shell在尝试读取该行的其余部分时遇到了EOF.
更新:rici显示,通过覆盖文件的不同示例,可以使用新写入的内容.重做:
script="`tr 12 21test.sh echo toggle: 1
第二行故意不使用bash的内置echo
命令,因为根据注释,有时不会导致bash重新读取脚本,但确切地说,当它发生时并且不是我不清楚时.当bash到达第三行时,bash输出新写入的切换值.这与我之前的例子之间的相关区别似乎是,在这里,bash可以在到达第三行时寻找当前位置,而在我之前的例子中,这是不可能的,因为该位置不再存在,因为文件是空.
在类Unix操作系统上,如果文件仍处于打开状态,则可以删除该文件.文件名将不再存在,但数据本身仍然存在,并且任何具有打开句柄的程序(包括bash)都可以继续使用该句柄读取(甚至写入).只有当最后一个程序关闭其句柄时,该文件才会被删除.
因此,从某种意义上说,是的,shell脚本可以自行删除,但在脚本执行完成之后才会真正删除它.
请注意,如果覆盖文件而不是删除文件,则会得到不同的结果.shell可以(并且确实)使用缓冲来避免一次读取一个字节,但缓冲区的大小有限.如果文件内容超出了shell已经读入内存的范围,它将看到新内容.如果检查系统的缓冲区大小,可以创建一个简单的示例.在我的系统上,恰好是8 KiB.所以包含的shell脚本
echo line 1 >test.sh # (8167 random characters) echo line 4
所以第二块数据是" cho line 4
",在我的系统上,输出
$ bash test.sh line 1 test.sh: line 4: e: command not found
因为e
已经读取了,并且shell在尝试读取该行的其余部分时遇到了EOF.
更新:rici显示,通过覆盖文件的不同示例,可以使用新写入的内容.重做:
script="`tr 12 21 <test.sh`" env echo "$script" >test.sh echo toggle: 1
第二行故意不使用bash的内置echo
命令,因为根据注释,有时不会导致bash重新读取脚本,但确切地说,当它发生时并且不是我不清楚时.当bash到达第三行时,bash输出新写入的切换值.这与我之前的例子之间的相关区别似乎是,在这里,bash可以在到达第三行时寻找当前位置,而在我之前的例子中,这是不可能的,因为该位置不再存在,因为文件是空.