Docker run直接执行nosetests提示命令未找到问题求助
看起来你遇到的问题有点诡异——进入容器能正常运行nosetests,但直接用docker run执行命令却提示找不到。我来帮你拆解一下可能的原因和解决方案:
首先纠正一个小误解
你执行的命令:
docker run --rm pfp printenv && echo --- && ls /usr/local/bin | grep -i nose
这里的&&是主机Shell的分隔符,只有第一个printenv是在容器内执行的,后面的echo和ls都是在你的本地主机上运行的!所以你看到的theano-nose是主机上的文件,不是容器里的,这解释了为什么你进入容器能找到/usr/local/bin/nosetests,但这个命令输出里看不到它。
可能的原因和解决方法
1. 尝试用绝对路径执行nosetests
既然已经确认nosetests在/usr/local/bin下,直接用绝对路径执行命令,绕过PATH查找的问题:
docker run --rm pfp /usr/local/bin/nosetests .
如果这个能正常运行,说明问题确实出在PATH的解析上。
2. 检查容器默认Shell的PATH
Docker默认用/bin/sh执行命令,而你进入容器用的是/bin/bash,两者的PATH可能存在细微差异(虽然你的printenv显示PATH包含/usr/local/bin,但不妨验证一下)。可以执行以下命令查看/bin/sh下的PATH:
docker run --rm pfp /bin/sh -c "echo \$PATH && whereis nosetests"
如果发现/usr/local/bin不在/bin/sh的PATH里,需要在Dockerfile中明确设置PATH:
ENV PATH=/usr/local/bin:$PATH
把这行加到Dockerfile的末尾,重新构建镜像即可。
3. 确认nosetests的安装方式和权限
- 如果你的
install.sh里是用pip install --user nose安装的,那么nosetests会被安装到/root/.local/bin下,这个路径默认不在PATH里。解决方法要么重新安装时去掉--user参数,要么把这个路径加入PATH:ENV PATH=/root/.local/bin:$PATH - 检查nosetests的可执行权限:在容器内执行
ls -l /usr/local/bin/nosetests,确保它有x权限(即权限位包含rwx)。如果没有,执行chmod +x /usr/local/bin/nosetests,并把这行加到Dockerfile里。
4. 修复Dockerfile里的环境变量小错误
你的Dockerfile里设置LD_LIBRARY_PATH时,变量引用少了美元符号:
ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64:/usr/lib:/usr/lib64:{LD_LIBRARY_PATH}
应该改成:
ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64:/usr/lib:/usr/lib64:${LD_LIBRARY_PATH}
虽然这个错误可能不是导致nosetests找不到的直接原因,但修复它能避免其他潜在问题。
总结
优先尝试用绝对路径执行nosetests,如果有效,再排查PATH的问题;同时检查nosetests的安装方式和权限,以及Dockerfile里的环境变量设置。这些步骤应该能帮你解决问题。
内容的提问来源于stack exchange,提问作者Bastienm

