且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

一个shell脚本可以删除或覆盖自己?

更新时间:2023-12-05 11:10:58

在类Unix操作系统,删除文件是可能的,如果它仍然是开放的。该文件的名称将不复存在,但数据本身也依然存在,并且有一个打开的句柄,包括bash的任何程序,可以继续使用该句柄来读取(甚至写)。最后一个程序关闭,只有当它的句柄确实该文件确实被删除。

On Unix-like operating systems, removing a file is possible if it is still open. The file name will no longer exist, but the data itself does remain, and any programs that have an open handle, including bash, can continue to read (and even write) using that handle. Only when the last program closes its handle does the file really get deleted.

所以,从某种意义上说,是的,一个shell脚本可以自行删除,但它不会的真正的进行,直到脚本执行结束后删除。

So, in a sense, yes, a shell script can delete itself, but it won't really be deleted until after the execution of that script finishes.

请注意,您得到不同的结果,如果你的覆盖的文件,而不是删除它。壳可以(做)使用缓冲,以避免每次读一个字节,但缓冲区具有有限的大小。如果文件内容的变化超出了外壳已经读入内存,它会看到新的内容。如果您检查您的系统缓冲区的大小是你可以创建一个简单的例子。在我的系统,它正好是8昆明植物研究所。因此,一个shell脚本,它包含

Note that you get different results if you overwrite the file instead of deleting it. Shells may (and do) use buffering to avoid reading one byte at a time, but the buffer has a finite size. If the file contents change beyond what the shell has already read into memory, it will see the new content. You can create a simple example of this if you examine what the buffer size for your system is. On my system, it happens to be 8 KiB. So a shell script that contains

echo line 1
>test.sh
# (8167 random characters)
echo line 4

因此​​,数据的第二块是町线4 ,我的系统中,输出


$ bash test.sh
line 1
test.sh: line 4: e: command not found

因为电子已经被读取,而且外壳EOF遇到试图读取该行的其余部分时。

because the e has already been read, and the shell encountered EOF when trying to read the rest of the line.

更新:罗杰斯国际商品指数显示,随着覆盖文件的不同的例子,新写入的内容也习惯。返工是:

Update: rici shows that with a different example of overwriting the file, the newly written contents do get used. Reworking that:

script="`tr 12 21 <test.sh`"
env echo "$script" >test.sh
echo toggle: 1

第二行故意不使用bash的内置回声命令,因为有时不会导致的bash重新读了剧本,每次的意见,但是当它precisely并没有我不清楚。当它到达三号线的bash输出新写​​入的触发值。这一点,我前面的例子之间的相关差异似乎是,在这里,庆典可以寻求到当前位置,当它到达三线,而在我前面的例子,那是不可能的,因为那个位置已不存在,因为该文件空的。

The second line intentionally doesn't use bash's built-in echo command, because that sometimes doesn't cause bash to re-read the script, per the comments, but precisely when it does and doesn't is unclear to me. bash outputs the newly written toggle value when it gets to line three. The relevant difference between this and my earlier example seems to be that here, bash can seek to the current position when it gets to line three, whereas in my earlier example, that is impossible, because that position no longer exists, as the file is empty.