用新版本替换bash脚本会导致运行中的脚本实例失败

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (16)

我在服务器上运行java程序中的bash脚本。我刚刚上传了一个新版本的脚本,打算在下一轮脚本中使用该版本。我并不是想中断现有的、正在运行的脚本实例。然而,我刚从我的300台服务器收到100多个崩溃通知。我猜是用新版本替换运行中的bash脚本导致了这一点。但是,这需要运行bash脚本在到达每个新步骤时从磁盘读取。这就是它的工作原理吗?

bash脚本的运行版本运行一些射线跟踪软件。每次跑步需要2个小时。分步骤从5分钟到1.5小时不等。脚本总是在完成脚本中的一个步骤后报告崩溃。它从来没有报告说,已经在运行的子步骤崩溃。有些崩溃报告没有找到我在脚本中找不到的命令。不同的撞车报告不同的地方。

帮助

编辑:我使用scp将脚本复制到所有300台服务器上。文件在文件系统上被替换。这不是共享文件。

提问于
用户回答回答于

SiegeX是半右的-bash会将整个脚本加载到内存中,所以即使进程运行时删除了它的源文件,脚本也可以继续运行。但是bash还将检查源文件是否在脚本运行时被更新。重新打开文件,查找到脚本的当前位置,然后从该位置继续运行脚本。

这里有一个概念证明脚本:

# If you modify a script, will it change the behavior of
# processes that are currently running that script?
# Does this script print "Foo" or "Bar"?

cat >foo.sh <<EOF
sleep 5
echo Foo
EOF

bash foo.sh &
sleep 2

cat >foo.sh <<EOF
sleep 5
echo Bar
EOF

wait

因此,如果关心当前运行bash脚本的进程,那么就不要修改bash脚本的源文件。

然而,此脚本显示“foo”。bash脚本的“当前位置”总是在行的开头或结尾。
echo "sleep 5 ; echo Foo" > foo.sh
bash foo.sh &
sleep 2
echo "sleep 5 ; echo Bar" > foo.sh
wait
用户回答回答于

如果可以避免,不要更新正在运行的系统

删除脚本是一回事,但是修改它可能会产生更“有趣”的结果。

此外,更改复制和/或网络挂载的文件会引入特定于文件系统和部署协议的行为。在本地硬挂载上的简单测试或在读取文件的同一个系统上修改网络挂载的测试都无法准确地建模。

此外,“上传”这个文件到300个服务器上会带来各种各样的复杂,我们的溢出者可能没有足够的信息来分析。

ISTM你的问题可能与更新有关。我认为神秘的命令可能来自bash阅读部分脚本从旧版本和一部分从新版本。我确实知道,如果可能的话,应该在更新时关闭子系统。

扫码关注云+社区