0

我希望向 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)下载到~/data/skyfieldstations.txt下载到同一个load.timescale()地方load.tle(stations_url)

在容器中运行时的行为

3 个 deltat 文件被下载两次:

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

这令人沮丧,因为此时它们已经存在并且它们污染了当前目录。请注意,stations.txt最终出现在正确的位置(~/data/skyfield

如果容器以交互方式运行exec(open("script.py").read()),则在 python shell 中调用会再次提供正常行为。谁能重现这个问题?很难说它是来自 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

然后(假设构建的图像被标记为 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 run 并不能解决问题,但有助于更好地说明问题。我认为它可能来自 Skyfield,因为 github 上的一些最近的问题看起来非常相似,但并不完全相同。

4

1 回答 1

1

这里的简单解决方案是添加-t到您的docker run命令以分配伪 TTY:

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

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

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

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

请参阅Docker run with pseudoTTY (-t) 提供即时标准输出,没有它的缓冲会发生另一种解释(可能比我的更好)。

于 2017-09-12T22:33:54.863 回答