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
并寻找它在当前工作目录中。
我写了一个简单的 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
并寻找它在当前工作目录中。