从 shell 脚本运行 python 文件时出现 ModuleNotFoundError 错误

Posted

技术标签:

【中文标题】从 shell 脚本运行 python 文件时出现 ModuleNotFoundError 错误【英文标题】:ModuleNotFoundError error when running a python file from shell script 【发布时间】:2021-12-29 14:41:59 【问题描述】:

我有一个 python 文件 download.py 我正在其中导入一个模块 opc

现在,这个 python 文件从 shell 脚本 build.sh 调用,例如:

python3 $(pwd)/scripts/download.py -d $dir_name

当我运行 shell 脚本时,我收到以下错误:

Traceback (most recent call last):
  File "/home/ray/Desktop/repo/image-builder/scripts/download.py", line 14, in <module>
    from opc.utils import file_utils, logger
ModuleNotFoundError: No module named 'opc'

这是调用 shell 脚本的方式:

sudo sh scripts/src/build.sh

我有一个活动的虚拟环境,我安装了这个包。这个包也有

>pip list

Package                           Version
--------------------------------- -------
attrs                             21.2.0
.
.
opc                               0.8.0

有趣的是,当我直接运行 python 代码时

python3 scripts/download.py -d dir_path

它工作正常。我没有收到ModuleNotFoundError 错误。

另外,这也很好用:

❯ python3
Python 3.8.10 (default, Sep 28 2021, 16:10:42) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import opc.utils.global_vars as g
>>> print(g.LOCAL_HOST)
127.0.0.1
>>>

目录结构:

/home/ray/Desktop/repo/image-builder/scripts/download.py
/home/ray/Desktop/repo/image-builder/scripts/src/build.sh

我正在运行以下命令:

/home/ray/Desktop/repo/image-builder

【问题讨论】:

我正在尝试重现它。这个 OPC 包是来自 pip 的opc?或者它是一个不同的?我问是因为版本不适合我。 不是来自 pip 【参考方案1】:

这可能是因为当您调用 shell 脚本时,python 路径与您运行 Python 解释器时不同。如果是这种情况,有几种方法可以解决这个问题。

如果您手动切换到与download.py 相同的目录并从那里运行您的python 脚本会发生什么?比如:

cd scripts
python download.py -d <some-dir>

这行得通吗,还是你仍然遇到同样的问题?

在这样的 shell 脚本中,我首先确保脚本将始终从文件系统中完全相同的位置调用 python 应用程序,这样我就不会遇到这些 python 路径问题。如果您确定python download.py -d &lt;some-dir&gt;download.py 在同一目录中工作,那么您可以在您的shell 脚本中添加类似的内容(假设您的shell 脚本和download.py 在同一目录中):

pushd "$0%/*" # this changes directory to the directory where the shell script itself lives

# do your stuff here - run your python app, etc.

popd # returns to whatever directory we were originally in

这样,我总是可以从我所在的任何目录调用 shell 脚本,而且我知道它的行为方式相同 - 当前目录不再相关。

我不会使用$(pwd),因为它会给出当前目录,而当前目录会有所不同,因此如果你这样做,你的 shell 脚本只有在从正确目录中调用时才能正常工作。

【讨论】:

以上是关于从 shell 脚本运行 python 文件时出现 ModuleNotFoundError 错误的主要内容,如果未能解决你的问题,请参考以下文章

运行 shell 脚本时出现“换行符”意外

从脚本填充数据库时出现 Django Heroku DataError

在 Python 3 中导入模块时出现 AttributeError

创建目录时出现 Oozie shell 操作问题

在 WSL 中运行 shell 脚本时出现“E: Invalid operation update”错误

尝试运行可执行 Python 脚本时出现致命的 Python 错误