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

用新版本替换bash脚本是否会导致脚本的运行实例失败,bash,Bash,我正在服务器上运行java程序中的bash脚本。我刚刚上传了一个新版本的脚本,打算在下一次运行脚本时使用这个版本。我并不是要中断脚本的现有运行实例。然而,我刚刚收到300台服务器发出的100多个崩溃通知。我猜是用新版本替换正在运行的bash脚本导致了这种情况。但是,这需要运行的bash脚本在进入每个新步骤时从磁盘读取数据。这就是它的工作原理吗 bash脚本的运行版本运行一些光线跟踪软件。每次运行需要2小时。子步骤需要5分钟到1.5小时。脚本总是在完成脚本中的一个步骤后报告崩溃。它从不报告已经运行

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

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

救命啊


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

在调用时,bash将派生一个新进程并将脚本加载到内存中。除非脚本引用自身,否则它仍然可以工作。下面是一个脚本的示例,该脚本从磁盘中删除自身,直到尝试通过
$0

输入 输出 如果可以避免,请不要更新正在运行的系统
删除脚本是一回事,但修改它可能会产生更“有趣”的结果

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

此外,“上传”这个文件到300台服务器会带来各种奇妙的复杂性,我们这些飞越者可能没有足够的信息来分析


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

SiegeX有一半是正确的-bash会将整个脚本加载到内存中,因此即使在进程运行时删除了脚本的源文件,脚本也可以继续运行。但是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

我不确定自从mob的答案被接受以来,情况是否发生了变化,但在bash 4.3.46(如ubuntu 16.04附带的版本)中,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

rm foo.sh

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

wait
#如果修改脚本,它会改变脚本的行为吗
#当前正在运行该脚本的进程?
#此脚本是否打印“Foo”或“Bar”?

猫>foo.sh谢谢。我就是这么想的。我的问题一定在别处。不,这个解释是错误的。看见(确实,运行的bash可以在删除脚本后存活下来。)好吧……我将文件分别发送到所有300台服务器,因此这不是网络文件共享问题。关闭它们并让它们重新启动并非小事,但可能是正确的做法。虽然我认为开场白的建议是可靠的,对于另一个问题,我可能会投赞成票,但我不认为这对回答这个具体问题有用。“飞越者”到底是什么?哇。这正是我遇到的。我相当肯定这样的事情是基于行为发生的,但我认为SiegeX是正确的。感谢您花时间回复。不,mob的解释是错误的,它说它在调用时读取所有内容并检查更新。注意这个问题。(即使Emacs与您无关。=)它还说明了如何修改正在运行的shell脚本。
# 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
echo "sleep 5 ; echo Foo" > foo.sh
bash foo.sh &
sleep 2
echo "sleep 5 ; echo Bar" > foo.sh
wait
# 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

rm foo.sh

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

wait