Node.js中setInterval内调用writeFileSync触发EACCES权限问题排查
问题分析与解决方法
核心原因排查
1. 工作目录(CWD)在setInterval执行时发生变更
脚本启动时的当前工作目录,在setInterval回调执行期间可能被其他代码(比如process.chdir()调用)或外部操作修改,导致相对路径database.json指向了一个root用户也没有写入权限的目录。
- 验证方法:在setInterval回调内打印
process.cwd(),和脚本启动时的目录对比; - 解决方法:使用绝对路径访问文件,彻底避免依赖相对路径:
const path = require('path'); const dbFilePath = path.resolve(__dirname, 'database.json'); // 在setInterval回调内使用dbFilePath替代'database.json' fs.writeFileSync(dbFilePath, JSON.stringify(data));
2. 文件权限被其他进程篡改或文件被锁定
setInterval执行期间,可能有其他进程(如系统备份工具、第三方服务、文件同步程序)修改了database.json的权限,或者占用文件导致写入失败。
- 验证方法:
- 报错时执行
ls -l database.json,查看文件权限是否变为非root可写; - 使用
lsof database.json检查是否有其他进程占用该文件;
- 报错时执行
- 解决方法:确保文件权限始终为root所有(执行
chown root:root database.json),同时避免其他进程频繁操作该文件。
3. Node.js权限缓存或上下文执行异常
虽然进程以root运行,但Node.js的文件系统模块可能缓存了早期的权限信息,或者setInterval的回调在不同的执行上下文里触发了异常的权限检查逻辑。
- 解决方法:
- 强制在回调内重新解析文件的绝对路径;
- 尝试用异步方法
fs.writeFile替代writeFileSync,避免同步操作的上下文冲突。
4. 系统安全模块(SELinux/AppArmor)的限制
树莓派可能启用了SELinux或AppArmor等安全模块,即使root用户也会被限制某些定时任务的文件写入操作。
- 验证方法:临时关闭安全模块测试(如执行
sudo systemctl stop apparmor),如果问题消失则说明是安全规则限制; - 解决方法:配置安全模块的规则,允许该脚本写入目标文件。
内容的提问来源于stack exchange,提问作者Roy Kolak
相关产品推荐
相关产品推荐

