所以我发现在Linux中做这件事的难度很大:
# a.sh
while true
do
some stuff
sh a.sh
done
我希望能够更新脚本并让它自行修复。这样的事情被认为是安全的而不是
# a.sh
while true
do
wget http://127.0.0.1/b.sh
sh b.sh
done
# b.sh
some stuff
通过这种方式,我可以更新脚本b.sh
,并且自a.sh
调用它以来,下一次执行会被强制更新吗?
答案 0 :(得分:0)
如果您希望进程更改其源代码并重新启动自身,并且您不希望同时运行多个(略有不同)的进程副本,那么您需要以某种方式终止父进程。你怎么做这个并不重要;例如,如果代码的“重写自我”部分仅在实际需要重写时触发,那么您可以在调用重写脚本的行之后放置“退出”。 (我怀疑像mv -f b.sh a.sh && sh a.sh && exit
这样的东西也可能有效,因为我认为整个行将在脚本被销毁之前发送给Bash解释器。)
如果您确实希望运行多个流程副本,那么您需要找到一些限制此数字的方法。例如,您可能让脚本检查在分叉之前已经运行了多少次迭代。
请注意,在这两种情况下,这都假定您的脚本已经准确地修改了自己,这至少可以说是一个棘手的问题。你正在踩着危险的地方。
最后,如果您真正想要的是一个守护程序,它会在它死亡时自动重新启动(这听起来就像您在评论中所描述的那样),还有其他方法可以实现这一点。我不太熟悉这种事情通常是如何完成的,但我想在shell脚本中你可以简单地使用trap
。 (trap a.sh EXIT
可能就足够了,但是如果你以后认定你犯了错误,这会使你的 难以永久杀死。)
答案 1 :(得分:0)
您可能想要exec
脚本。 exec
用新的执行环境替换执行中的脚本,因此它永远不会返回(除非启动指示的程序时出现问题)。
除非你知道自己在做什么,否则覆盖正在运行的脚本是个坏主意。 bash在启动脚本时不会将整个文件读入内存,因此它将在覆盖文件中的相同字节偏移处继续。
最后,如果您的意思是sh
,请不要使用bash
。 sh
可能是一个不同的shell,即使它是bash
,它也会有不同的行为。