我有多个运行bash脚本的远程站点,由cron启动(经常运行 - 10分钟或更短时间),其中一个作业是同步“脚本”目录。我的想法是让我能够在一个位置(数据中心的服务器)编辑脚本,而不必登录每个远程站点并手动进行任何编辑。问题是,同步当前运行同步的脚本的最佳选项是什么? (我希望这很清楚。)
我想会同步一个当前运行的脚本会非常糟糕。如果我将其作为脚本的最后一个语句运行,以下内容是否可行?利弊?利弊?其他选择??
if [ -e ${newScriptPath} ]; then
mv ${newScriptPath} ${permanentPath}" | at "now + 1 minute"
fi
我看到的一个问题是,如果我使用“1分钟”(这是“at”的最小增量),并且脚本结束,并且cron在“at”替换脚本之前启动下一个作业,它可能会尝试在下一次运行脚本时替换它....
答案 0 :(得分:1)
在执行期间更改脚本文件确实很危险(请参阅this previous answer),但有一个技巧(至少在我测试过的bash版本中)强制bash读取将整个脚本放入内存中,因此如果它在执行期间发生变化,则不会产生任何影响。只需将脚本包装在{}
中,然后使用显式退出( in {}
),这样如果有任何内容被添加到文件的末尾,它将不会成为执行:
#!/bin/bash
{
# Actual script contents go here
exit
}
警告:正如我所说,这适用于我测试过的bash版本。我对其他版本或其他shell没有任何承诺。在将其投入生产使用之前,使用您正在使用的外壳进行测试。
此外,在同步过程中是否存在任何其他脚本运行的风险?如果是这样,你要么需要对所有这些使用这个技巧,要么找到一些通用的方法来检测正在使用的脚本并推迟更新它们直到以后。
答案 1 :(得分:0)
所以我最终使用" at"实用程序,但仅在文件更改时。我有一个" .cur"和" .new"本地计算机上的脚本版本。如果两者的MD5相同,我什么都不做。如果它们不同,我会等到主脚本完成后再强制复制" .new"到" .cur"在另一个剧本中。
我为update_script创建了相同的锁文件(名称),因此如果我要更改它,则第一个脚本的另一个实例不会运行..
参与主剧本......
file1=`script_cur.sh`
file2=`script_new.sh`
if [ "$file1" == "$file2" ] ; then
echo "Files have the same content"
else
echo "Files are different, scheduling update_script.sh at command"
at -f update_script.sh now + 1 minute
fi