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 帮你干了?