SQLite创建的数据库未继承父目录默认ACL权限,如何解决?
这个问题的核心原因是:SQLite在创建数据库文件时会显式指定文件权限(默认通常是八进制0644,由编译时的SQLITE_DEFAULT_FILE_PERMISSIONS参数决定),这会绕过系统默认ACL的继承逻辑——当程序主动设置权限位时,系统不会自动应用默认ACL的基础权限配置,而是保留程序指定的权限后再叠加ACL规则。这就是为什么你看到数据库文件的基础权限是-rw-r--r--+,而不是其他文件的-rw-rw-r--+。
下面提供几种针对性的解决方案:
方法1:通过环境变量覆盖SQLite默认权限
你可以设置SQLITE_DEFAULT_FILE_PERMISSIONS环境变量,直接指定SQLite创建文件时使用的权限值。比如要得到rw-rw-r--(对应八进制0664),在创建数据库前执行:
export SQLITE_DEFAULT_FILE_PERMISSIONS=0664 sqlite3 my_database.db
这样创建的数据库文件会直接使用0664作为基础权限,结合你已配置的默认ACL,最终ls输出就会和其他文件一致,组内成员的读写权限也能正常生效。
方法2:用SQLite的PRAGMA指令调整umask
SQLite支持通过PRAGMA umask设置创建文件时的umask值。如果你希望组拥有读写权限,可以设置umask为0002(默认权限0666减去该umask后就是0664):
sqlite3 my_database.db PRAGMA umask=0002; -- 执行你的数据库操作,比如创建表、插入数据等
注意这个设置只对当前数据库连接有效,每次打开数据库都需要重新配置,适合脚本或交互式使用场景。
方法3:手动修正已创建文件的权限(临时方案)
如果只是临时处理已存在的数据库文件,可以用setfacl手动补全ACL规则,同时修正基础权限位:
# 给my_group组添加读写权限 setfacl -m g:my_group:rw my_database.db # 修正基础组权限为可写 chmod g+w my_database.db
这个方法能快速让现有文件权限符合要求,但无法自动应用到新创建的数据库,适合应急处理。
额外注意
SQLite的WAL日志文件(my_database.db-wal)和共享内存文件(my_database.db-shm)也会有同样的权限问题,所以上述方法需要确保覆盖这些辅助文件的创建场景(比如保持环境变量生效,或在连接时设置PRAGMA)。
内容的提问来源于stack exchange,提问作者Bruno Quint

