ubuntu 16.04 中可执行 .desktop 文件的 sqlite3 问题。长期支持

sqlite3 problems with executable .desktop file in ubuntu 16.04. LTS

我写了一个简单的 Python 文件 Example.py 像这样

import sqlite3
conn = sqlite3.connect('test.db')
c=conn.cursor()
Cursor = c.execute("SELECT position,department from STAFF")
conn.close()

当我运行命令行中的文件window

$python Example.py

它工作得很好。在 Ubuntu 16.04 中使其可执行后。 LTS

$sudo chmod -x Example.py

并尝试通过 Example.desktop 文件打开它,其中包含

[Desktop Entry]
Name=Example
Exec=/home/workspace/Example.py 
Terminal=False
Type=Application
Icon=/home/Desktop/Example.jpg,

它不起作用。通过插入图像的开头,我可以将问题跟踪到第

$Cursor = c.execute("SELECT position,department from STAFF").

有人知道为什么会这样以及如何解决它吗?

由于您使用相对路径 (sqlite3.connect('test.db')) 加载您的 SQLite 文件,因此您从中执行脚本的工作目录很重要。当你 运行 一个 .desktop 文件时,它的执行就像你从桌面启动你的脚本一样,你的脚本在那里寻找 test.db,而你的实际 test.db 文件在 /home/workspace.

要使您的脚本从 /home/workspace 执行,因此所有相对路径都基于它,您需要将 Path 属性添加到 [Desktop Entry] 部分:

[Desktop Entry]
Name=Example
Path=/home/workspace
Exec=/home/workspace/Example.py
# etc.

现在当你的 Example.py 运行 时,它 运行 就像你 cd /home/workspace && /home/workspace/Example.py 一样,因此你所有的本地路径都是相对于 /home/workspace.您甚至可以直接在 Python:

中验证您当前的工作目录
import os

print(os.getcwd())

如果您在未指定 Path 的情况下从 .desktop 文件执行此操作,它将为您提供桌面作为当前工作目录。

UPDATE - 如果您想知道为什么 import some_other_file 在不设置工作目录的情况下工作,那是因为 Python 自动添加了主目录脚本在其 sys.path 中执行,保证 import 语句也可以搜索脚本的主文件夹等。

然而,这仅适用于 import 语句,它不适用于文件访问或任何类似的相对路径,这就是为什么 sqlite 无法打开正确的文件,如果您没有为它提供路径(或将当前工作路径设置为脚本所在的位置)。

如果您不想指定工作目录但仍想使用具有相对路径的文件,则必须获取脚本的路径,然后在将路径提供给 SQLite 打开之前附加您的文件名,类似于:

import os
import sqlite3

# there are some exceptions where this will not work but for your case it's enough:
home_dir = os.path.realpath(os.path.dirname(__file__))  # your script's home dir

conn = sqlite3.connect(os.path.join(home_dir, "test.db")) 
# etc.

现在,在您的情况下,sqlite 将获得到 test.db 的实际路径(如果它位于您脚本的主文件夹中),而不是仅仅获得空白 test.db 并寻找它在当前工作目录中。