结束 ssh 会话后在后台运行 python/matplotlib 的问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2443702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-04 00:39:52  来源:igfitidea点击:

Problem running python/matplotlib in background after ending ssh session

pythonsshbackgroundmatplotlibtkinter

提问by Jamie

I have to VPN and then ssh from home to my work server and want to run a python script in the background, then log out of the ssh session. My script makes several histogram plots using matplotlib, and as long as I keep the connection open everything is fine, but if I log out I keep getting an error message in the log file I created for the script.

我必须使用 VPN,然后从家里 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"

I'm assuming that it doesn't know where to create the figures I want since I close my X11 ssh session. If I'm logged in while the script is running I don't see any figures popping up (although that's because I don't have the show() command in my script), and I thought that python uses tkinter to display figures. The way that I'm creating the figures is,

我假设它不知道在哪里创建我想要的数字,因为我关闭了 X11 ssh 会话。如果我在脚本运行时登录,则看不到任何图形弹出(尽管这是因为我的脚本中没有 show() 命令),并且我认为 python 使用 tkinter 来显示图形。我创造数字的方式是,

loglog()
hist(list,x)
ylabel('y')
xlabel('x')
savefig('%s_hist.ps' %source.name)
close()

The script requires some initial input, so the way I'm running it in the background is

该脚本需要一些初始输入,所以我在后台运行它的方式是

python scriptToRun.py << start>& logfile.log&

Is there a way around this, or do I just have to stay ssh'd into my machine?

有没有办法解决这个问题,还是我只需要通过 ssh 连接到我的机器?

Thanks.

谢谢。

采纳答案by Vicki Laidler

It looks like you're running in interactive mode by default, so matplotlib wants to plot everything to the screen first, which of course it can't do.

看起来你默认是在交互模式下运行的,所以 matplotlib 想先把所有东西都绘制到屏幕上,这当然做不到。

Try putting

尝试放置

ioff()

at the top of your script, along with making the backend change.

在脚本的顶部,同时进行后端更改。

reference: http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.ioff

参考:http: //matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.ioff

回答by Mark

I believe your matplotlib backend requires X11. Look in your matplotlibrc file to determine what your default is (from the error, I'm betting TkAgg). To run without X11, use the Agg backend. Either set it globally in the matplotlibrc file or on a script by script by adding this to the python program:

我相信你的 matplotlib 后端需要 X11。查看您的 matplotlibrc 文件以确定您的默认值是什么(根据错误,我打赌 TkAgg)。要在没有 X11 的情况下运行,请使用 Agg 后端。通过将其添加到 python 程序,可以在 matplotlibrc 文件中全局设置它,也可以通过脚本在脚本上设置它:

import matplotlib
matplotlib.use('Agg')

回答by Bolster

Sorry if this is a stupid answer, but if you're just running a console session, would 'screen' not suffice? Detachable sessions, etc.

对不起,如果这是一个愚蠢的答案,但如果您只是在运行控制台会话,“屏幕”还不够吗?可拆卸会话等

回答by Robert Menteer

If you are running on a *nix OS the problem is your session is terminated and all processes requiring a session are also terminated when you disconnect. More specifically all your processes are sent a SIGHUP (signal hang-up). The default handling of SITHUP is to terminate the process. If you want you script to continue it needs to ignore the signal. The easiest way to do that assuming you start your script via the command line it to run it using the nohup command:

如果您在 *nix 操作系统上运行,问题是您的会话终止,并且当您断开连接时,所有需要会话的进程也将终止。更具体地说,您的所有进程都会发送一个 SIGHUP(信号挂断)。SITHUP 的默认处理是终止进程。如果您希望脚本继续,则需要忽略该信号。最简单的方法是假设您通过命令行启动脚本,然后使用 nohup 命令运行它:

nohup python scriptToRun.py << start>& logfile.log&

nohup normally sends standard out and standard error to the file nohup.out in the current directory. Since you're redirecting already output nohup.out will not be created.

nohup 通常将标准输出和标准错误发送到当前目录中的文件 nohup.out。由于您正在重定向,因此不会创建输出 nohup.out。