以递归方式调用sh脚本的安全方法

时间:2015-01-27 07:01:36

标签: linux bash

所以我发现在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调用它以来,下一次执行会被强制更新吗?

2 个答案:

答案 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,请不要使用bashsh可能是一个不同的shell,即使它是bash,它也会有不同的行为。

相关问题