Cron任务无权限访问文件,但Shell脚本可正常执行
我编写了一个需定时执行的Shell脚本my-job.sh,其中包含读取SQLite数据库文件并进行数据操作的逻辑,核心代码如下:
sqlite3 -json -header "/path/to/MyDatabase.db" < "/path/to/ExportScript" > "/path/to/save/output.json"
手动执行bash my-job.sh或sh my-job.sh时脚本可正常运行,但通过Cron任务执行时,出现如下错误:
Error: unable to open database "/path/to/MyDatabase.db": authorization denied
我已尝试以下操作:
- 将
MyDatabase.db的权限设置为664、666、777等,均无效; - 以root用户(
sudo su -)创建新Cron任务,手动执行脚本正常,但Cron任务仍报错; - 在普通用户和root用户的crontab文件顶部设置
SHELL=/bin/bash。
相关环境信息:
- MacOS 12.7
sqlite33.37.0bash3.2.57
请问我还遗漏了什么?
给Cron授予全磁盘访问权限
MacOS从Catalina开始,后台进程受隐私权限严格限制。打开「系统偏好设置」→「安全性与隐私」→「隐私」标签,找到「全磁盘访问」,点击左下角锁图标解锁,然后点击「+」按钮,在弹出的文件选择窗口中按Cmd+Shift+G,输入/usr/sbin/cron并添加,之后重启电脑或执行命令重启Cron:sudo launchctl stop com.vix.cron && sudo launchctl start com.vix.cron。检查数据库父目录的权限
不要只修改数据库文件的权限,还要确保它所在的父目录有执行权限(比如权限设为755),否则进程无法进入目录访问文件。执行命令:chmod 755 /path/to/确认数据库不在SIP保护目录
如果数据库文件存放在/System、/usr(除/usr/local)等受系统完整性保护(SIP)的目录下,即使root用户也无法通过Cron访问。建议将数据库移到~/Documents、/usr/local等非SIP保护的目录。完善Cron的环境变量配置
在crontab文件顶部补充PATH设置,确保所有命令和路径都能被正确识别:PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin SHELL=/bin/bash也可以在脚本
my-job.sh的开头添加相同的PATH导出语句。使用完整的sqlite3命令路径
Cron的默认PATH很有限,直接用sqlite3可能存在路径问题,建议在脚本中使用完整路径:/usr/bin/sqlite3 -json -header "/path/to/MyDatabase.db" < "/path/to/ExportScript" > "/path/to/save/output.json"
内容的提问来源于stack exchange,提问作者ebbishop

