覆写执行bash脚本文件 [英] Overwrite executing bash script files

查看:231
本文介绍了覆写执行bash脚本文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果执行bash脚本文件被覆盖会发生什么?它会继续执行旧的文件或覆盖文件?

What will happen if the executing bash script file is overwritten? Will it continue execute the old file or overwritten file ?

例如
/etc/test.sh具有以下内容

For example /etc/test.sh has the following contents

CP /test.sh /etc/test.sh

cp /test.sh /etc/test.sh

推荐答案

庆典一般不的的加载整个剧本提前,所以覆盖脚本可以取消predictable后果。例如,我刚刚创建包含此脚本:

bash generally does not load the entire script in advance, so overwriting the script can have unpredictable consequences. For example, I just created a script containing this:

#!/bin/bash
echo start old file
sleep 20
echo end old file

...并运行它。虽然它正在睡觉,我与此稍有不同的脚本改写它:

...and ran it. While it was sleeping, I overwrote it with this slightly different script:

#!/bin/bash
echo started new file
sleep 20
echo end new file

在此输出所得的:

$ ./test.sh 
start old file
./test.sh: line 4: 0: command not found
end new file

实际情况是,庆典已通过休眠20 \\ n行中(包括终止换行符行)睡觉前阅读。当它后,持续的,它的文件的在读取下一个字节位置的下一个命令的,并且由于第二行已经得到两个字节长(开始 - >开始),它绕看完了新睡眠行的最后两个字节(休眠20 \\ n - >0 \\ n),试图执行0命令,并得到一个错误。然后,它运行的新内容的最后一行。 pretty凌乱的,对吧?

What happened was that bash had read through the "sleep 20\n" line (including the line terminating newline) before sleeping. When it continued after that, it read the next command from the next byte position in the file, and since the second line had gotten two bytes longer ("start" -> "started"), it wound up reading the last two bytes of the new sleep line ("sleep 20\n" -> "0\n"), trying to execute "0" as a command, and getting an error. It then runs the final line of the new contents. Pretty messy, right?

幸运的是,有一种方法来强制bash,如果它在运行时被变更为整个脚本加载到内存中,这样就不会感到困惑:

Fortunately, there's a way to force bash to load the entire script into memory so it won't get confused if it gets changed while running:

#!/bin/bash
{
    echo start old file
    sleep 20
    echo end old file
    exit
}

{迫使壳至少通过匹配读} ,以便正确解析命令,和退出然后确保它永远不会尝试执行被后添加任何}

The { forces the shell to read at least through the matching } in order to properly parse the command, and the exit then makes sure it'll never try to execute anything that gets added after that }.

顺便说一句,我是用的bash版本3.2.48(1) - 释放(在OS X 10.8.5)测试此;其他版本可能不同的表现...

BTW, I was testing this with bash version 3.2.48(1)-release (on OS X 10.8.5); other versions may behave differently...

更新:其它版本确实表现不同。我试着用版本4.3.0(1) - 释放相同的测试(NetBSD的6.1.4以下),并继续运行旧code中的文件的内容已经被取代了。显然,现在缓存在8KB块中的文件(请参阅this unix.se答案)。

UPDATE: Other versions do indeed behave differently. I tried the same test with version 4.3.0(1)-release (under NetBSD 6.1.4), and it continued to run the old code after the file's contents had been replaced. Apparently it now buffers the file in 8KB blocks (see this unix.se answer).

这篇关于覆写执行bash脚本文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆