在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.data , deltat.preds和Leap_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)给出即时标准输出,缓冲发生没有它的另一种解释(可能比我更好)。