Bash here语句搭配inotifywait监控失效 无法更新循环内全局变量
问题根源
你修改后的代码无法运行的核心原因是$()命令替换的执行逻辑:
- 你给
inotifywait加了--monitor参数,这个参数会让inotifywait持续监听事件,永远不会主动退出 - 而
$()命令替换必须等待内部命令完全执行结束后,才会把所有输出一次性返回给<<<对应的字符串重定向 - 也就是说你的代码会永远卡在等待
inotifywait退出的阶段,自然不会有任何事件进入while循环处理。
可行替代方案
方案1:使用进程替换(最通用的Bash方案)
这是适配inotifywait --monitor持续输出场景的标准写法,既可以让while循环在当前Shell进程运行,又能实时接收inotifywait的事件输出:
VARIABLE=1 while read -r INPUT_FILE do VARIABLE=42 # 可在此处打印验证变量确实被修改 echo $VARIABLE done < <(/usr/bin/inotifywait --monitor --quiet -e moved_to -e close_write --format '%w%f' "$CACHE_DIR")
注意:
< <()是Bash的进程替换语法,两个尖括号之间必须有空格,该语法仅支持Bash、Zsh等现代Shell,不支持POSIX sh。
方案2:开启lastpipe选项(适合非交互式脚本场景)
如果你的脚本运行在非交互式环境下,可以开启Bash的lastpipe选项,让管道最后一个命令在当前Shell进程执行,不需要修改原有管道结构:
# 脚本开头加上这两行即可 shopt -s lastpipe set +m VARIABLE=1 /usr/bin/inotifywait --monitor --quiet -e moved_to -e close_write --format '%w%f' "$CACHE_DIR" | while read -r INPUT_FILE do VARIABLE=42 done
该方案需要Bash 4.2及以上版本支持,
set +m作用是关闭作业控制,非交互式脚本默认就是关闭状态,通常可以省略。
方案3:使用临时文件中转变量(兼容POSIX sh标准)
如果需要兼容POSIX sh标准,可以把需要修改的变量值写入临时文件,需要读取变量时从临时文件取值即可:
VARIABLE=1 # 创建临时文件存储变量值 TEMP_VAR=$(mktemp) echo 1 > "$TEMP_VAR" /usr/bin/inotifywait --monitor --quiet -e moved_to -e close_write --format '%w%f' "$CACHE_DIR" | while read -r INPUT_FILE do echo 42 > "$TEMP_VAR" done # 后续需要使用变量时从临时文件读取 VARIABLE=$(cat "$TEMP_VAR") rm "$TEMP_VAR"
内容的提问来源于stack exchange,提问作者Starid
相关产品推荐
相关产品推荐

