linux 补丁脚本,linux – 在运行时替换shell脚本

我有一个运行“补丁”脚本的电路板.补丁脚本始终在后台运行,它是一个运行以下伪代码的shell脚本:

while true; do

# checks if a patch tar file exists and if yes then do patching

sleep 10

done

此脚本位于/opt/patch.sh,它由SystemV init脚本启动.

问题是,当脚本找到tar时,它会提取它,并且里面有一个名为patch.sh的shell脚本,它特定于tar的内容.

当/opt/patch.sh中的脚本找到tar时,它会执行以下操作:

tar -xf /opt/update.tar -C /mnt/update

mv /mnt/update/patch.sh /opt/patch.sh

exec /opt/patch.sh

它将替换为另一个脚本并从同一位置执行它.

这样做会出现任何问题吗?

解决方法:

如果通过就地写入来替换文件(inode保持不变),那么打开它的任何进程都会在从文件读取时查看新数据.如果通过取消链接旧文件并创建具有相同名称的新文件来替换它,则inode编号会更改,并且保持文件打开的任何进程仍将具有旧文件.

mv可能会执行任何操作,具体取决于文件系统之间是否发生移动…要确保获得全新文件,请先取消链接或重命名原始文件.像这样的东西:

mv /opt/patch.sh /opt/patch.sh.old # or rm

mv /mnt/update/patch.sh /opt/patch.sh

这样,即使在移动之后,正在运行的shell仍将具有旧数据的文件句柄.

也就是说,据我所测试,Bash在执行任何循环之前读取整个循环,因此只要执行保持在循环内,对底层文件的任何更改都不会更改正在运行的脚本.退出循环后,Bash从循环结束后的位置继续读取输入文件.我不确定读取完整循环是否只是为了它可以检查语法(它可能缺少最后完成),或者它是否用于缓存目的.

脚本中定义的任何函数也会加载到内存中,因此将脚本的主要逻辑放到一个函数中,只在末尾调用它会使脚本非常安全,不会对文件进行修改:

#!/bin/sh

main() {

do_stuff

exit

}

main

无论如何,测试脚本被覆盖时会发生什么并不难:

$cat > old.sh <

#!/bin/bash

for i in 1 2 3 4 ; do

# rm old.sh

cat new.sh > old.sh

sleep 1

echo $i

done

echo will this be reached?

EOF

$cat > new.sh <

#!/bin/bash

echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

EOF

$bash old.sh

随着rm old.sh注释掉,脚本将就地更改.如果没有评论,将创建一个新文件.

标签:bash,linux,shell,buffer

来源: https://codeday.me/bug/20190813/1647647.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值