watchexec

> watchexec — 文件一改就自动跑命令,省去反复手动触发的麻烦。 如果你写过代码、跑过构建、编译过文档,大概率经历过这样的场景:改一行代码,切回终端,按上箭头,回车,等结果,发现报错,再改,再切,再回车……循环到怀疑人生。更崩溃的是,有时候你忘了手动触发,调试了半天才发现“哦,我还没重新跑”。 Watchexec 就是来解决这个痛点的。它监控你指定的文件或目录,一旦检测到变化(保存、新增、删除、重命名),立即自动执行你设定的命令。而且它**跨平台**——macOS、Linux、Windows 都能用,不需要依赖 inotify、fsevents 这类系统级工具,开箱即用。 ### 它能干什么,解决什么问题 简单说,Watchexec 是一个“文件变化触发器”。你告诉它“盯着这个文件夹”,再告诉它“文件变了就运行这条命令”,剩下的事它全包了。 具体场景包括: - **自动重启开发服务器**:比如你在写一个 Node.js 后端,每次改完代码自动跑 `node server.js`,不用手动 Ctrl+C 再重启。 - **自动编译**:写 Rust 项目时自动执行 `cargo build`,写 LaTeX 时自动 `xelatex main.tex`。 - **自动运行测试**:保存测试文件后自动执行 `pytest` 或 `cargo test`,第一时间看到红绿。 - **自动刷新静态网站**:配合 Hugo、Jekyll 等静态生成器,文件保存后自动重新生成页面。 - **批量处理任务**:比如监控图片文件夹,有新图片就自动压缩、上传。 和同类工具(比如 nodemon、entr、fswatch)相比,Watchexec 最大的优势是**通用性**:它不绑定任何语言或框架,任何命令行工具都能驱动。而且它处理信号传递非常干净,不会出现子进程残留的问题。 ### 下载方式 官网在这里,所有下载链接都在首页就能找到: [Watchexec 官网](https://watchexec.github.io/) 如果你喜欢直接去 GitHub 看 release,也可以去: [GitHub Releases 页面](https://github.com/watchexec/watchexec/releases) ### 安装方法 安装方式很灵活,挑你顺手的来: **macOS(Homebrew)** ```bash brew install watchexec ``` **Linux(包管理器)** - Ubuntu/Debian:`sudo apt install watchexec`(如果官方源没有,先加仓库,或者用下面 cargo 方式) - Arch Linux:`sudo pacman -S watchexec` - Fedora:`sudo dnf install watchexec` **Windows(Scoop / Chocolatey)** ```bash scoop install watchexec # 或者 choco install watchexec ``` **通用方式(Rust 的 cargo)** 如果你有 Rust 环境,一行搞定: ```bash cargo install watchexec-cli ``` **直接下载二进制** 去官网或 GitHub Releases,找到对应系统的压缩包,解压后把可执行文件扔到 PATH 目录里(比如 Linux 的 `/usr/local/bin`,Windows 的 `C:\Windows\System32`)。 ### 基础使用教程 先来几个最常用的例子,感受一下。 **例子 1:监控当前目录所有文件,文件变化时运行 `echo "changed"`** ```bash watchexec echo "changed" ``` 保存任何一个文件,终端就会打印“changed”。这是最简单的验证方式。 **例子 2:监控特定扩展名文件,变化时运行脚本** ```bash watchexec -e js,ts -- node build.js ``` 只监控 `.js` 和 `.ts` 文件,其他文件变动不触发。 **例子 3:监控某个子目录** ```bash watchexec -w src -w tests -- cargo test ``` 只盯着 `src` 和 `tests` 两个目录,其他地方随便改都不管。 **例子 4:延迟触发(防抖)** ```bash watchexec --debounce 500ms -- cargo check ``` 你连续保存文件时,它会等 500 毫秒内没有新变化才执行。避免你疯狂按 Ctrl+S 时反复触发。 **例子 5:忽略某些文件或目录** ```bash watchexec --ignore node_modules --ignore "*.log" -- npm run build ``` 忽略 `node_modules` 目录和所有 `.log` 文件,其他变化都触发构建。 **例子 6:只监控文件变化,不监控新增/删除** ```bash watchexec --watch . --on-modify -- cargo run ``` 默认情况下,新增、删除、修改、重命名都会触发。加上 `--on-modify` 就只响应修改事件。 **例子 7:传递信号给子进程(比如重启服务器)** ```bash watchexec --restart --signal SIGTERM -- python server.py ``` `--restart` 表示先终止旧进程再启动新进程。`--signal` 指定发什么信号,默认是 SIGTERM,也可以改成 SIGKILL。这对开发 web 服务器非常有用:每次改代码,服务器自动重启,你甚至感觉不到中断。 ### 进阶技巧 **1. 结合 `clear` 命令,每次执行前清屏** ```bash watchexec --clear -- cargo run ``` 每次触发时先清屏,输出更清爽。也可以写成 `--clear=reset`,效果类似。 **2. 使用 Shell 管道和复杂命令** 如果你要执行多条命令,用引号包起来: ```bash watchexec -- "npm run build && npm run deploy" ``` 注意:Windows 上用 `&` 代替 `&&`,或者用 PowerShell 的 `;`。 **3. 处理大量文件变化的“节流”** 有时候一次 git pull 或批量复制会触发成百上千次变化。用 `--debounce` 合并事件,同时用 `--no-video`(如果支持)减少日志: ```bash watchexec --debounce 2s --no-meta -- echo "bulk change detected" ``` `--no-meta` 忽略元数据变化(比如权限、时间戳),只关注内容。 **4. 只监控特定文件名模式** 除了 `-e` 按扩展名过滤,还可以用 `--filter` 写更复杂的规则: ```bash watchexec --filter "*.rs" --filter "!target/*" -- cargo build ``` `!` 开头表示排除。规则支持 glob 模式。 **5. 在后台运行,并记录日志** ```bash nohup watchexec --restart -- node app.js > watchexec.log 2>&1 & ``` 然后你可以关掉终端,它仍在后台跑。适合服务器环境。 **6. 与 Tmux / Screen 配合** 在 Tmux 里开一个窗格跑 Watchexec,另一个窗格写代码。保存文件后,自动触发,你立刻看到结果。比 IDE 内置终端还顺手。 **7. 监控远程文件(通过 SSHFS / NFS)** Watchexec 支持监控挂载的文件系统。如果你在本地用 SSHFS 挂载了远程目录,直接 `watchexec -w /mnt/remote` 即可。注意网络延迟,`--debounce` 设大一点。 ### 小提醒 - **不要监控整个 `node_modules`**:除非你想体验 CPU 100% 的酸爽。用 `--ignore` 排除掉。 - **Windows 用户注意路径分隔符**:用反斜杠 `\` 或正斜杠 `/` 都行,但建议统一用正斜杠避免转义问题。 - **信号处理**:如果你要终止 Watchexec 本身,按 Ctrl+C 即可。它会先向子进程发信号,再退出,不会留下孤儿进程。 ### 总结 Watchexec 是一个“无废话”的工具。它不像一些重量级构建工具那样自带文件监听功能,但正因为轻量和通用,反而能适配几乎所有场景。无论你是写 Python、Go、Rust、JavaScript,还是处理 Markdown、LaTeX、图像文件,它都能成为你工作流里的“自动按钮”。 下次再手动按上箭头回车时,想想:是不是该让 Watchexec 帮你干了?