首页 > 解决方案 > 脚本在同事设备上完美运行,但给了我“无效的跨设备链接”

问题描述

我的脚本在同事设备上完美运行(MacOSX 和 Docker Desktop 和我一样),但每次都给我同样的错误,它不会移动或只有一半,deps目录中的库:

OSError: [Errno 18] Invalid cross-device link: '/tmp/pip-target-dzwe_2kc/lib/python/numpy' ->
 '/foo/python/numpy'

我的脚本:

#!/bin/bash
export PKG_DIR='python'
export SIDE_DEPS_DIR='deps'

rm -rf ${PKG_DIR} && mkdir -p ${PKG_DIR}
rm -rf ${SIDE_DEPS_DIR} && mkdir -p ${SIDE_DEPS_DIR}

docker run --rm -v $(pwd):/foo -w /foo lambci/lambda:build-python3.8 \
    pip3 install -r requirements.txt -t ${PKG_DIR}

# move stuff to deps
find /${PKG_DIR} -maxdepth 1 -type d \
\( -name "pandas*" -o -name "numpy*" -o -name "numpy.libs*" -o -name "scipy*" -o -name "scipy.libs*" \) -exec mv '{}' ${SIDE_DEPS_DIR} \;

# zip side dependencies
zip -r ge_deps.zip deps
# zip layer
zip -r layers-python38-great-expectations.zip python

这是一个脚本,它使用公共 lambda docker 映像来创建 lambda 层(基本上是一个包含库的 zip),并删除不需要的库以将它们放在另一个文件夹deps中。

上面的代码将使用公共 Docker 镜像 lambci / lambda 并将安装在空python目录中,这些库来自名为“great-expectations”的 python 包,有助于测试数据管道(在 requirements.xml 文件中指定)。 txt 和是great-expectations==0.12.7

我已经被这个问题困扰了一段时间,还没有找到解决方案。

标签: shelldocker-desktop

解决方案


刚才有这个确切的问题。

/tmp 和 /foo 是不同的设备 - /tmp 在 docker 操作系统中,而 /foo 映射到您的本地操作系统。

pip 似乎正在使用 shutil.rename() 将构建的包从 tmp 移动到最终输出位置 (/foo)。这失败了,因为它们是不同的设备。理想情况下,pip 将使用 shutil.move() 代替,这将处理跨设备移动。

作为一种解决方法,您可以在调用 pip 命令之前通过设置 TMPDIR 来更改 PIP 使用的临时文件夹。即export TMPDIR=/foo/tmp在 docker 映像中调用 pip 之前。因此,整个命令可能类似于

docker run --rm -v $(pwd):/foo -w /foo lambci/lambda:build-python3.8 \
    /bin/bash -c "export TMPDIR=/foo/tmp && pip3 install -r requirements.txt -t ${PKG_DIR}"

(从https://www.edureka.co/community/10736/how-to-run-multiple-commands-in-docker-at-once获取的多个命令解决方案- 接受更好的建议!)

这可能会更慢,因为它使用本地操作系统来存储临时文件,但它避免了跨设备从临时文件夹到最终输出文件夹的尝试“重命名”。


推荐阅读