英文:
Unable to import pandas on a linux service
问题
我正在尝试使用Python创建一个简单的服务,并且该服务需要导入pandas来操作数据框。我注意到当我使用"import pandas as pd"时,服务会失败。我创建了一个示例来展示这种行为。
脚本main2.py(位置:/home/silas/Desktop):
import pandas as pd
import logging
import time
while True:
print('hello world')
time.sleep(10)
my_service.service(位置:/etc/systemd/system):
[Unit]
Description=Example
After=network.target
[Service]
ExecStart=/usr/bin/python3 /home/silas/Desktop/main2.py
Restart=always
[Install]
WantedBy=default.target
我打开终端并执行了以下命令:
systemctl start my_service.service
systemctl enable my_service.service
systemctl status my_service.service
我得到的响应告诉我我的服务没有运行并且失败了:
my_service.service - Example
Loaded: loaded (/etc/systemd/system/my_service.service; enabled; vendor pr>
Active: failed (Result: exit-code) since Tue 2023-08-08 19:49:53 -03; 1min>
Main PID: 8776 (code=exited, status=1/FAILURE)
CPU: 63ms
如果我将脚本更改为:
import logging
import time
while True:
print('hello world')
time.sleep(10)
并执行以下命令:
systemctl stop my_service.service
systemctl disable my_service.service
systemctl start my_service.service
systemctl enable my_service.service
systemctl status my_service.service
我得到的响应告诉我服务正在运行:
my_service.service - Example
Loaded: loaded (/etc/systemd/system/my_service.service; enabled; vendor pr>
Active: active (running) since Tue 2023-08-08 19:54:31 -03; 10s ago
Main PID: 8952 (python3)
Tasks: 1 (limit: 8994)
Memory: 4.2M
CPU: 26ms
CGroup: /system.slice/my_service.service
└─8952 /usr/bin/python3 /home/silas/Desktop/main2.py
是否可以以这种方式使用pandas?如果可以,我做错了什么?如果不可能,我该如何创建一个使用pandas的服务?
注意1:Pandas已安装在我的机器上,我没有使用虚拟环境。
注意2:如果我使用python3 main2.py执行脚本,可以正常工作并且可以使用pandas。
注意3:如果我在终端中输入which python3,会显示my_service.service中配置的路径。
英文:
I'm trying to create a simple service using Python and the service needs to import pandas for manipulating dataframes. I noticed that when I use "import pandas as pd", the service failed. I created a example to show the behavior.
Script main2.py (location: /home/silas/Desktop):
import pandas as pd
import logging
import time
while True:
print('hello world')
time.sleep(10)
my_service.service (location: /etc/systemd/system):
[Unit]
Description=Example
After=network.target
[Service]
ExecStart=/usr/bin/python3 /home/silas/Desktop/main2.py
Restart=always
[Install]
WantedBy=default.target
I opened the prompt and executed the commands:
systemctl start my_service.service
systemctl enable my_service.service
systemctl status my_service.service
I got the response telling me that my service is not running and failed:
my_service.service - Example
Loaded: loaded (/etc/systemd/system/my_service.service; enabled; vendor pr>
Active: failed (Result: exit-code) since Tue 2023-08-08 19:49:53 -03; 1min>
Main PID: 8776 (code=exited, status=1/FAILURE)
CPU: 63ms
If I change the script to:
import logging
import time
while True:
print('hello world')
time.sleep(10)
And execute the commands:
systemctl stop my_service.service
systemctl disable my_service.service
systemctl start my_service.service
systemctl enable my_service.service
systemctl status my_service.service
I got the response telling me that the service is running:
y_service.service - Example
Loaded: loaded (/etc/systemd/system/my_service.service; enabled; vendor pr>
Active: active (running) since Tue 2023-08-08 19:54:31 -03; 10s ago
Main PID: 8952 (python3)
Tasks: 1 (limit: 8994)
Memory: 4.2M
CPU: 26ms
CGroup: /system.slice/my_service.service
└─8952 /usr/bin/python3 /home/silas/Desktop/main2.py
Is possible to use pandas in this way? If so, what I'm doing wrong? If is not possible, how can I create a service using pandas?
Obs1: Pandas is installed in my machine, I'm not using virtual environment.
Obs2: If I execute the script with python3 main2.py, works normally with pandas.
Obs3: If I type which python3 in my prompt, shows the path configured in my_service.service.
答案1
得分: 2
我发现我可以在我的.service文件中设置用户。我以以下格式设置了我的用户:
my_service.service:
[Unit]
Description=示例
After=network.target
[Service]
User=你当前的用户
ExecStart=/usr/bin/python3 /home/silas/Desktop/main2.py
[Install]
WantedBy=default.target
然后我使用了以下命令:
sudo systemctl restart my_service.service
该服务与pandas一起工作。
英文:
I discovered that I can set the user in my .service file. I set my user in this format:
my_service.service:
[Unit]
Description=Example
After=network.target
[Service]
User=your_current_user
ExecStart=/usr/bin/python3 /home/silas/Desktop/main2.py
[Install]
WantedBy=default.target
Then I used the command:
sudo systemctl restart my_service.service
The service worked with pandas.
答案2
得分: 2
你也可以将一个systemd服务运行在用户级别,将其放置在$XDG_CONFIG_HOME/systemd/user
目录下,并使用--user
标志启动该服务。对于我来说,$XDG_CONFIG_HOME
是~/.config
。
systemctl enable --now --user my_service.service
从那里开始,你需要在任何操作上都使用--user
标志,比如检查status
、disable
或stop
等。
英文:
You can also run a systemd service on the user level by putting it in $XDG_CONFIG_HOME/systemd/user
and start the service with the --user
flag. ($XDG_CONFIG_HOME for me is ~/.config
)
systemctl enable --now --user my_service.service
You would have to use the --user flag on anything for it from there, like checking the status
or disable
or stop
, etc
答案3
得分: 1
除了答案(只是一个附注)。
我们可以检查Python搜索模块的路径列表:
import logging
logging.basicConfig(
filename='/path/to/my_service.log',
level=logging.DEBUG,
filemode='a')
logging.debug('Importing pandas')
try:
import pandas
except Exception as e:
logging.error('Failed to import pandas', exc_info=True)
logging.debug('sys.path=[\n'+"\n".join(sys.path)+'\n]')
else:
logging.debug('Succesfully imported pandas')
我猜Pandas是以pip install --user pandas
的方式安装在用户文件夹中的。为了检查这一点,我们可以在REPL中运行:
import pandas; print(pandas.__file__) # 在这种情况下可能在/home/silas/.local/lib/python3/site-packages/pandas中的某个位置
当运行服务时,Python将由root用户启动。因此,sys.path
将被配置为忽略您的本地site-packages。可以手动添加路径,例如sys.path.append(your_pandas_path)
,但这很难是一个好决定。在服务中使用User=your_current_user
是正确的选择。
英文:
In addition to the answer (just a side note).
We can check the list of paths, where python is searching for modules:
import logging
logging.basicConfig(
filename='/path/to/my_service.log',
level=logging.DEBUG,
filemode='a')
logging.debug('Importing pandas')
try:
import pandas
except Exception as e:
logging.error('Failed to import pandas', exc_info=True)
logging.debug('sys.path=[\n'+"\n".join(sys.path)+'\n]')
else:
logging.debug('Succesfully imported pandas')
I guess that Pandas was installed like pip install --user pandas
in a user folder. To check this we can run in REPL:
import pandas; print(pandas.__file__) # maybe somewhere in /home/silas/.local/lib/python3/site-packages/pandas in this case
When running a service, python will be started by a root user. So sys.path
will be configured ignoring your local site-packeges. It's possible to add the path manually like sys.path.append(your_pandas_path)
but hardly it's a good decision. User=your_current_user
in a service is the right choice.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论