You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash脚本如何读取控制台日志实现nodemon服务崩溃自动重启

问题背景

我正在使用一个Web API,当该API崩溃时,我需要手动中断当前运行命令,再在控制台输入npm start完成重启。为减少重复操作,我尝试编写Bash脚本自动执行该重启流程,脚本代码如下:

npm start
while [ $? -ne 0 ]; do
    npm start
done

但该脚本未达到预期效果:API崩溃时正在运行的命令不会退出,因此不会返回对应退出码。API崩溃时终端会打印如下日志:

[nodemon] app crashed - waiting for file changes before starting...

需要实现的效果是:让Bash脚本读取到该条控制台日志时,自动触发操作完成服务重启。

解决方案

原有脚本失效的核心原因是:nodemon默认在应用崩溃后不会主动退出进程,而是进入挂起状态等待文件变更,因此shell拿不到非0退出码,循环重启逻辑完全无法触发。可以根据需求选以下两种方案实现:

方案1:使用nodemon原生配置(最简便)

不需要额外编写复杂的日志监听逻辑,直接修改启动参数即可适配原有循环脚本
nodemon自带崩溃退出的启动参数--exitcrash,添加该参数后,只要应用发生崩溃,nodemon就会直接以非0状态码退出,原有shell脚本的退出码判断逻辑就能正常生效。

  • 如果直接调用nodemon启动,把启动命令改为nodemon --exitcrash 你的入口文件.js
  • 如果是通过npm start封装启动,直接修改package.json里的start脚本,给nodemon命令加上--exitcrash参数即可。

方案2:编写日志监听脚本触发重启

如果需要保留nodemon默认行为、通过匹配指定日志触发重启,可以使用逐行读取进程输出的方式编写脚本,参考代码如下:

#!/bin/bash
while true; do
    # 启动服务,合并标准输出、错误输出,逐行读取日志
    npm start 2>&1 | while IFS= read -r line; do
        echo "$line" # 原样打印所有日志,不影响日常查看
        # 匹配到崩溃挂起的目标日志
        if [[ "$line" == *"[nodemon] app crashed - waiting for file changes before starting..."* ]]; then
            # 杀掉当前挂起的npm、nodemon进程
            pkill -f "npm start"
            pkill -f nodemon
            break
        fi
    done
    echo "检测到服务崩溃,2秒后重启..."
    sleep 2 # 留缓冲时间避免端口未释放导致启动失败
done

脚本使用注意事项:

  • 2>&1的作用是把错误输出合并到标准输出流,避免漏读日志导致匹配失效
  • 匹配到目标日志后需要主动杀掉挂起的相关进程,否则进程会一直卡在等待文件变更的状态
  • 重启间隔可以根据自己的服务启动速度调整,一般1-3秒即可

内容的提问来源于stack exchange,提问作者raphaelguionaud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 00:36:17