Debian下Apache执行脚本遇sqlite.py权限错误(直接运行正常)
问题描述
在Debian系统中,通过Apache2执行以下PHP脚本:
$pid = shell_exec(sprintf('nohup /bin/bash /home/debian/Desktop/Holibot/holi.sh > /dev/null 2>&1 & echo $!'));
holi.sh的作用是激活虚拟环境(venv)并运行Python脚本。但第三方库kerykeion调用requests_cache的sqlite.py时触发权限错误,报错信息如下:
2023-06-14 13:40:16,532 - KrInstance - ERROR - Error in fetching http://api.geonames.org/searchJSON: attempt to write a readonly database Which error comes from self.responses[cache_key] = cached_response File "/home/debian/Desktop/Holibot/venv/lib/python3.9/site-packages/requests_cache/backends/sqlite.py", line 283, in __setitem__ con.execute( sqlite3.OperationalError: attempt to write a readonly database
已对Python项目所有文件和文件夹递归设置chmod 777权限、chown www-data所有者,且直接执行sudo -u www-data bash -c "/home/debian/Desktop/Holibot/holi.sh"时无权限问题,为何Apache执行会出现该错误?
可能的原因及解决方法
- nohup执行时的工作目录不匹配
Apache调用shell_exec时,默认工作目录是Apache根目录(如/var/www/html),而sudo -u www-data直接执行时工作目录是当前终端目录或脚本所在目录。requests_cache默认会在当前工作目录创建sqlite缓存文件,若Apache工作目录对www-data无写入权限,就会触发只读错误。
解决:在holi.sh开头添加切换目录的命令:
cd /home/debian/Desktop/Holibot
AppArmor安全规则限制
Debian默认启用AppArmor,可能限制了Apache进程(www-data)对用户桌面目录(/home/debian/Desktop)的写入操作——即使文件权限设置正确,也会被安全规则拦截。而直接用sudo -u www-data执行时,不受AppArmor针对Apache的规则约束。
解决:- 临时关闭Apache的AppArmor强制规则测试:
sudo aa-complain /etc/apparmor.d/usr.sbin.apache2 - 若测试有效,可修改AppArmor规则,添加对
/home/debian/Desktop/Holibot/**的读写权限;或者将项目迁移到/var/www目录下,更符合Apache默认安全策略。
- 临时关闭Apache的AppArmor强制规则测试:
环境变量差异导致缓存路径错误
Apache执行时的环境变量与sudo -u www-data直接执行时存在差异,requests_cache可能读取了不同的配置,导致缓存文件路径指向了无权限的位置。
解决:在Python脚本中显式指定requests_cache的缓存文件路径到项目目录,示例:
import requests_cache requests_cache.install_cache('/home/debian/Desktop/Holibot/cache.sqlite')
内容的提问来源于stack exchange,提问作者T Tea Tie
相关产品推荐
相关产品推荐

