结束 ssh 会话后在后台运行 python/matplotlib 的问题
Posted
技术标签:
【中文标题】结束 ssh 会话后在后台运行 python/matplotlib 的问题【英文标题】:Problem running python/matplotlib in background after ending ssh session 【发布时间】:2011-01-27 11:21:28 【问题描述】:我必须先使用 ***,然后从家里通过 ssh 连接到我的工作服务器,并想在后台运行 python 脚本,然后退出 ssh 会话。我的脚本使用 matplotlib 制作了几个直方图,只要我保持连接打开一切都很好,但是如果我注销,我会在为脚本创建的日志文件中不断收到错误消息。
File "/Home/eud/jmcohen/.local/lib/python2.5/site-packages/matplotlib/pyplot.py", line 2058, in loglog
ax = gca()
File "/Home/eud/jmcohen/.local/lib/python2.5/site-packages/matplotlib/pyplot.py", line 582, in gca
ax = gcf().gca(**kwargs)
File "/Home/eud/jmcohen/.local/lib/python2.5/site-packages/matplotlib/pyplot.py", line 276, in gcf
return figure()
File "/Home/eud/jmcohen/.local/lib/python2.5/site-packages/matplotlib/pyplot.py", line 254, in figure
**kwargs)
File "/Home/eud/jmcohen/.local/lib/python2.5/site-packages/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
window = Tk.Tk()
File "/Home/eud/jmcohen/.local/lib/python2.5/lib-tk/Tkinter.py", line 1647, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: couldn't connect to display "localhost:10.0"
我假设自从我关闭 X11 ssh 会话后,它不知道在哪里创建我想要的数字。如果我在脚本运行时登录,我看不到任何数字弹出(尽管那是因为我的脚本中没有 show() 命令),并且我认为 python 使用 tkinter 来显示数字。我创建数字的方式是,
loglog()
hist(list,x)
ylabel('y')
xlabel('x')
savefig('%s_hist.ps' %source.name)
close()
脚本需要一些初始输入,所以我在后台运行它的方式是
python scriptToRun.py << start>& logfile.log&
有没有办法解决这个问题,还是我只需要通过 ssh 进入我的机器?
谢谢。
【问题讨论】:
你能运行 vnc 会话吗?或者,有 XFree NX 程序,但我从未使用过它。它就像 X11 会话的屏幕。 我对vnc了解不多。我认为更多的是用于控制本地网络上的计算机?我认为问题在于 x11 关闭,所以当我关闭 vnc 会话时,它不会给出相同的结果吗? 【参考方案1】:我相信您的 matplotlib 后端需要 X11。查看您的 matplotlibrc 文件以确定您的默认值是什么(从错误中,我打赌 TkAgg)。要在没有 X11 的情况下运行,请使用 Agg 后端。要么在 matplotlibrc 文件中全局设置它,要么通过脚本将其添加到 python 程序中:
import matplotlib
matplotlib.use('Agg')
【讨论】:
我将该行添加到程序的开头,但仍然收到相同的错误消息。 只对我有用:) 确保这 2 行在任何其他 matplotlib 的 pyplot / pylab / backends 引用之前。引用:“对 matplotlib.use() 的调用无效,因为已经选择了后端;matplotlib.use() 必须在 pylab、matplotlib.pyplot 或 matplotlib.backends 导入之前调用第一次”【参考方案2】:看起来你默认是在交互模式下运行的,所以 matplotlib 想先把所有的东西都绘制到屏幕上,这当然做不到。
试试看
ioff()
在脚本的顶部,同时进行后端更改。
参考:http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.ioff
【讨论】:
太棒了,完成了这项工作。非常感谢!【参考方案3】:对不起,如果这是一个愚蠢的答案,但如果您只是在运行控制台会话,“屏幕”还不够吗?可分离会话等。
【讨论】:
这可能是对您可能愚蠢的问题的愚蠢回答 :) 您所说的控制台会话、“屏幕”和可拆卸会话是什么意思?我运行它的方式是我在我的 OS X 机器 *** 上,然后通过终端 SSH 进入我工作的 linux 机器。 @Jamie,unix screen 命令允许您从终端分离,然后再重新连接。一旦你在终端提示符下,输入屏幕,启动你的程序。现在只需关闭您的 SSH 客户端。下次在该框上重新连接时,键入“screen -R”,然后您将返回上次中断的位置。当然,请参阅屏幕手册了解更多详细信息。 实际上 screen 给了我同样的显示错误(在使用 ioff() 的交互式控制台中运行 matplotlib 代码时) - 显然它与 matplotlib 不兼容。【参考方案4】:如果您在 *nix 操作系统上运行,问题是您的会话已终止,并且在您断开连接时所有需要会话的进程也会终止。更具体地说,您的所有进程都会发送一个 SIGHUP(信号挂断)。 SITHUP 的默认处理是终止进程。如果您希望脚本继续,则需要忽略该信号。假设您通过命令行启动脚本以使用 nohup 命令运行它,那么最简单的方法是:
nohup python scriptToRun.py << start>& logfile.log&
nohup 通常将标准输出和标准错误发送到当前目录中的文件 nohup.out。由于您正在重定向已经输出 nohup.out 将不会被创建。
【讨论】:
他的问题是由于 X11 连接失败。 在开头添加 nohup 似乎没有任何作用,得到了同样的错误信息。以上是关于结束 ssh 会话后在后台运行 python/matplotlib 的问题的主要内容,如果未能解决你的问题,请参考以下文章