如何在脚本中使用entr工具检测文件变更后执行命令并退出?
如何在脚本中使用entr工具检测文件变更后执行命令并退出?
嘿,我完全懂你的困扰——entr默认确实是一直循环监听的,想要让它触发一次就退出得用点小技巧,我来给你捋捋可行的方案,还有关于给调用脚本设置变量的问题怎么解决。
首先说entr本身的解决办法:
entr默认会在执行完命令后继续监听文件变化,但我们可以在执行的命令里主动终止entr进程。entr会给子命令暴露一个ENTR_PID环境变量,指向它自己的进程ID,所以我们可以在命令结尾加上kill $ENTR_PID,这样命令执行完就会让entr直接退出。比如:
echo "你要监听的文件名" | entr '你的命令; kill $ENTR_PID'
举个具体例子,如果你要监听config.ini,执行逻辑后还要把值传回父脚本,可以这么写:
# 父脚本中捕获entr命令的输出作为变量 updated_var=$(echo "config.ini" | entr -s 'echo "新的配置值"; kill $ENTR_PID') echo "父脚本里的变量已更新:$updated_var"
这里用-s选项让entr用shell执行命令,确保kill这类语法能正常工作;而直接在子shell里设置变量是无法影响父脚本的,所以用输出捕获的方式传递值才是靠谱的做法。
再说说你提到的inotifywait——如果你觉得entr的写法有点绕,inotifywait其实更贴合你的需求,因为它默认就是触发一次事件后就退出的,不需要额外处理退出逻辑。比如:
inotifywait -e modify,create "目标文件" >/dev/null && 你的命令
把inotifywait的输出重定向到/dev/null是为了避免它的日志信息干扰后续逻辑。同样要传变量的话,也是用捕获输出的方式:
my_var=$(inotifywait -e modify config.ini >/dev/null && echo "更新后的值")
总结一下:
- 用entr的话,核心是通过
kill $ENTR_PID让它执行一次后退出,配合输出捕获传递变量 - 用inotifywait的话更直接,默认就是单次触发,操作起来更省心
你可以根据自己的习惯选哪个,两种都能实现你要的「检测变更→执行命令→退出」的流程。
备注:内容来源于stack exchange,提问作者gamb1t9
相关产品推荐
相关产品推荐

