【问题标题】:SQlite permissions not enough for executionSQlite 权限不足以执行
【发布时间】:2024-04-25 00:35:02
【问题描述】:

我正在基于 sqlite3 和 python 在树莓派上开发一个小项目。其中一个脚本从传感器读取数据并将其写入数据库(sensor_update.py),另一个(cgi 脚本,hello.py)读取数据库中的最后一个条目并将其打印在网站上。 问题是脚本无法正确写入和读取数据库。我将数据库和脚本的所有权都设置为 www-data,但是当我尝试执行数据库编写脚本时,出现以下错误:

Traceback (most recent call last):
  File "sensor_update.py", line 35, in <module>
    log_temperature(temp)
  File "sensor_update.py", line 15, in log_temperature
    curs.execute("INSERT INTO temps values(datetime('now'), (?))", (temp,))
sqlite3.OperationalError: attempt to write a readonly database

我已经知道这很可能意味着权限不正确。但是 ls -l 给出的输出应该表明我做的一切都是正确的:

pi@raspberrypi:/usr/lib/cgi-bin $ ls -l
total 20
-rwxr-xr-x 1 www-data www-data 744 Jan 16 20:54 hello.py
-rwxr-xr-x 1 www-data www-data 475 Jan 16 20:40 hello.py.backup
-rwxr-xr-x 1 www-data www-data 163 Jan  3 22:40 hello.py.save
-rwxr-xr-x 1 www-data www-data 197 Jan  3 22:40 hello.py.save.1
-rwxr-xr-x 1 www-data www-data 698 Jan 16 21:11 sensor_update.py

pi@raspberrypi:/var/www $ ls -l
total 12
drwxr-xr-x 2 root     root     4096 Jan 11 08:31 html
-rwxr-xr-x 1 www-data www-data 8192 Jan 16 21:11 log.db

此外,cron 作业似乎不适用于 sensor_update.py 脚本。当命令前面带有 sudo 时,这两个程序都会产生预期的输出。
Sensor_update.py 代码:

#!/usr/bin/env python

import Adafruit_BMP.BMP085 as BMP085
import os
import datetime
import sqlite3

dbname = '/var/www/log.db'
# store the temperature in the database
def log_temperature(temp):

    conn=sqlite3.connect(dbname)
    curs=conn.cursor()
    temp = str(temp)
    curs.execute("INSERT INTO temps values(datetime('now'), (?))", (temp,))

    # commit the changes
    conn.commit()

    conn.close()

def display_data():

    conn=sqlite3.connect(dbname)
    curs=conn.cursor()

    for row in curs.execute("SELECT * FROM temps"):
        print str(row[0])+"     "+str(row[1])

    conn.close()


sensor = BMP085.BMP085()
temp=sensor.read_temperature()
log_temperature(temp)
display_data()

hello.py 代码(cgi 脚本):

#!/usr/bin/env python

import Adafruit_BMP.BMP085 as BMP085
import cgi
import cgitb
import sqlite3

cgitb.enable()
dbname = '/var/www/log.db'

def get_data():
        conn=sqlite3.connect(dbname)
        curs=conn.cursor()
        curs.execute("SELECT * FROM temps ORDER BY timestamp DESC LIMIT 1")
        result = curs.fetchone()
        return result

if __name__ == "__main__":

        result=get_data()
        print result

apache2 日志片段:

[Tue Jan 16 21:55:10.812282 2018] [cgi:error] [pid 964] [client ---:52835] Premature end of script headers: hello.py

【问题讨论】:

  • 请同时发布代码或最小示例。否则无法验证。没有它,帮助会更加困难。
  • @ZF007 完成,尽管它们使用 sudo 执行得很好。

标签: python sqlite raspberry-pi


【解决方案1】:

SQLite 需要在与数据库相同的目录中创建一个“日志”文件以支持 ACID 事务,因此它需要对数据库所在目录以及数据库本身具有写访问权限。

/var/www 可能属于root 而不是www-data(您没有使用ls -al,但看到html 目录属于www-data,我假设/var/www也是)。 SQLite 无法创建日志,因此它以只读模式打开以防止可能的损坏。

要么更改/var/www 的权限,要么将数据库放在打开数据库的进程具有写入权限的文件夹中。

【讨论】:

    最近更新 更多