我正在尝试将 Bokeh 图导出到图像。为此,我使用了 export_png
方法,该方法在底层使用了 PhantomJS 和 Selenium。但是,我遇到了运行时错误
RuntimeError: PhantomJS is not present in PATH or BOKEH_PHANTOMJS_PATH.
Try "conda install phantomjs" or "npm install -g phantomjs-prebuilt"
可以重现此行为:
笔记本
import shutil
shutil.which('phantomjs') or 'not found'
# --> "not found"
在同一个 virtualenv 中使用 IPython
import shutil
shutil.which('phantomjs') or 'not found'
# --> "/home/<user>/miniconda/envs/p36/bin/phantomjs"
[编辑]
笔记本服务器作为 Linux (Ubuntu) 上的服务运行。我认为问题来自于此,因为当我手动启动笔记本服务器时,在笔记本上可以很好地找到 phantomJS 路径。这里是详细的 systemd 文件:
[Unit]
Description=Jupyter Notebook
After=multi-user.target network.target
[Service]
User=<myuser>
Group=<mygroup>
EnvironmentFile=/etc/environment
Type=idle
Restart=always
RestartSec=3
ExecStart=/home/<user>/miniconda3/envs/tensorflow/bin/jupyter-notebook --no-browser --notebook-dir="/home/<user>/src"
[Install]
WantedBy=multi-user.target
[解决方案]
这个问题更多的是一个 systemd 问题,而不是 Python 问题:使用的 $PATH
环境变量是 root 用户的环境变量,而不是指定用户的环境变量。在运行服务脚本之前,我没有找到任何明确的方法来加载 .bashrc 文件。然后,解决方案是使用一个环境文件,其中我声明了 $PATH
变量,其方式与在 .bashrc
文件中的声明方式相同。此后一切都变得很糟糕。
最佳答案
没有(也永远不会有)内置的加载方式 ~/.bashrc
在 systemd 中启动进程之前指定用户。
[Nit:如果您要在点文件中设置环境变量,请在 ~/.bash_profile
中进行设置,不是~/.bashrc
。前者由所有登录 shell 获取(大约每次登录一次),后者由每个交互式 shell 获取(并且不是由登录 shell 获取,因此 DE 的根进程不会获取这些变量)。]嗯>
systemd 不是 bash 解释器。 ~/.bashrc
可能包含任意 bash 代码,而不仅仅是环境变量赋值,因此 systemd 无法实现此类功能。
因此,如果您需要运行任意 shell 代码,只需显式执行即可:
ExecStart=/bin/bash -c '...'
关于python - jupyter 笔记本上找不到 PhantomJS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53464583/