微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在不使用子shell的情况下检测当前脚本是否已更改? 并启动新脚本

如何解决在不使用子shell的情况下检测当前脚本是否已更改? 并启动新脚本

是否可以在不使用 subshel​​l 命令的情况下让正在运行的脚本查看它是否已更改/更新?

如果已更新,则启动新脚本并杀死旧脚本。

以前我为它使用了一个单独的文件,所以当我创建文件时,脚本检测到它。但是,如果您正在运行脚本的多个实例,这可能会非常混乱

if [[ -f /mnt/g/update.tt ]]; then script.sh 2 && kill $$ ;fi

这个函数将被放置在一个大约需要 0.8 秒的循环中,这就是为什么没有子 shell 是重要的。

解决方法

也许:

age_of_script=$(( $(date +%s) - $(stat -c %Y "$0") ))
running_time=$SECONDS

if (( running_time > age_of_script )); then
    # script has been updated since I started running
    exec "$0" 2
fi

正如 that other guy 评论的那样,使用 exec替换当前进程。


使用 bash 4.3+,您可以使用:

bash_root=${BASH%/bin/bash}
if [[ -d "$bash_root/lib/bash" ]]; then
  enable -f "$bash_root/lib/bash/finfo" finfo
  file_age() { echo $(( $(printf '%(%s)T' -1) - $(finfo -m "$1") )); }
else
  file_age() { echo $(( $(printf '%(%s)T' -1) - $(stat -c %Y "$1") )); }
fi
age_of_script=$(file_age "$0")

仍然使用 subshel​​l 进行命令替换,但如果您的 bash 构建具有可加载模块,您可能不需要使用任何外部工具


对于后代,stat 与可加载 finfo 的快速基准

$ file_age() { echo $(( $(printf '%(%s)T' -1) - $(stat -c %Y "$1") )); }
$ time for ((i=0; i<1000; i++)); do x=$(file_age /etc/hosts); done

real    0m14.750s
user    0m2.288s
sys     0m4.139s
$ file_age() { echo $(( $(printf '%(%s)T' -1) - $(finfo -m "$1") )); }
$ time for ((i=0; i<1000; i++)); do x=$(file_age /etc/hosts); done

real    0m7.162s
user    0m1.148s
sys     0m2.085s
,

自动更新脚本的最佳和最简单的方法是将脚本修改戳与您在脚本开头创建的临时文件进行比较。

  scriptupdate=$(mktemp)

只要确保你只运行一次 mktemp,并且在任何循环之外,否则脚本会一遍又一遍地更新控制文件,使其比脚本更新..

那你只需要对比一下脚本文件和临时文件,看看脚本是不是从不,然后重启脚本

if [[ $0 -nt $scriptupdate ]]; then
  exec $0 $@
fi
 

Exec 用新脚本替换正在运行的脚本 $0 是当前脚本的完整路径和名称 $@ 将参数传递给新的运行。

,

您可以创建一个参考文件,然后继续检查当前脚本是否比该参考新:

#!/bin/bash
reference=$(mktemp)
thisscript="${BASH_SOURCE[0]}"
trap 'rm "$reference"' EXIT

printf '\nStarting\n'
while true
do
  if [[ "$thisscript" -nt "$reference" ]] 
  then
    rm "$reference"
    exec "$thisscript"
  fi
  printf "beep boop "
  read -t 0.8
done

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?