在Docker容器中,Skyfield.api加载器的行为有所不同

我希望为Skyfield指定一个下载目录,如下所示:

http://rhodesmill.org/skyfield/files.html

这是我的脚本:

from skyfield.api import Loader load = Loader('~/data/skyfield') # Next line downloads deltat.data, deltat.preds, Leap_Second.dat in ~/data/skyfield ts = load.timescale() t = ts.utc(2017,9,13,0,0,0) stations_url = 'http://celestrak.com/NORAD/elements/stations.txt' # Next line downloads stations.txt in ~/data/skyfield AND deltat.data, deltat.preds, Leap_Second.dat in $PWD !!! satellites = load.tle(stations_url) satellite = satellites['ISS (ZARYA)'] 

预期的行为(在docker工人以外工作)

3个deltat文件( deltat.datadeltat.predsLeap_Second.dat )通过load.timescale()下载到〜/ data / skyfield中load.timescale()load.tle(stations_url)

在容器中运行时的行为

3 deltat文件下载两次:

  • 一次在指定的文件夹中调用load.timescale()
  • 另一次在当前目录中的呼叫load.tle(stations_url)

这是令人沮丧的,因为他们已经存在在这一点,他们污染当前的目录。 请注意, 站点 .txt结束在正确的地方( 〜/ data / skyfield

如果容器是以交互方式运行的 ,那么在python shell中调用exec(open("script.py").read())会再次发出正常的行为 。 任何人都可以重现这个问题? 很难说它来自python,docker或skyfield。

dockerfile只是这两行:

 FROM continuumio/anaconda3:latest RUN conda install -c astropy astroquery && conda install -c anaconda ephem=3.7.6.0 && pip install skyfield 

然后(假设构build的图像被标记为astro),我运行它:

 docker run --rm -w /tmp/working -v $PWD:/tmp/working astro:latest python script.py 

这里是输出(假设在运行之前文件夹是空的):

 [#################################] 100% deltat.data [#################################] 100% deltat.preds [#################################] 100% Leap_Second.dat [#################################] 100% stations.txt [#################################] 100% deltat.data [#################################] 100% deltat.preds [#################################] 100% Leap_Second.dat 

编辑

添加-t到docker运行并没有解决问题,但有助于更好地说明问题。 我认为它可能来自Skyfield,因为最近github上的一些问题看起来很相似,尽pipe不完全相同。

这里简单的解决scheme是添加-t到你的docker run命令来分配一个伪TTY:

 docker run --rm -t -w /tmp/working -v $PWD:/tmp/working astro:latest python script.py 

你所看到的是由打印行和非基于TTY的标准输出缓冲引起的。 高达100%的百分比可能印在没有换行符的行上。 然后在100%之后再次用换行符打印。 通过缓冲,这会导致打印两次。

当您使用TTY运行相同的命令时,没有缓冲,并且实时打印行,所以换行实际上按需要工作。

代码path实际上并没有运行两次:)

看到docker运行pseudoTTY(-t)给出即时标准输出,缓冲发生没有它的另一种解释(可能比我更好)。