如何运行从任何位置调用Python脚本的Bash脚本?

我有一个Python脚本,说myscript.py ,使用相对模块导入,即from .. import module1 ,其中我的项目布局如下:

 project + outer_module - __init__.py - module1.py + inner_module - __init__.py - myscript.py - myscript.sh 

我有一个Bash脚本,说myscript.sh ,这是我的python脚本的包装,如下所示:

 #!/bin/bash python -m outer_module.inner_module.myscript $@ 

这可以执行myscript.py并根据需要将参数转发给我的脚本,但只有在上面显示的project目录中调用./outer_module/inner_module/myscript.sh时才起作用。

我怎样才能使这个脚本从任何地方工作? 例如,我怎样才能使这个工作像bash /root/to/my/project/outer_module/inner_module/myscript.sh

这是我的尝试:

当从其他地方执行myscript.sh ,我得到错误: No module named outer_module.inner_module 。 然后,我尝试了另一种方法来从任何地方执行bash脚本,将myscript.shreplace为:

 #!/bin/bash scriptdir=`dirname "$BASH_SOURCE"` python $scriptdir/myscript.py $@ 

当我执行如上所示的myscript.sh ,我得到以下内容:

 Traceback (most recent call last): File "./inner_module/myscript.py", line 10, in <module> from .. import module1 ValueError: Attempted relative import in non-package 

这是由于在myscript.py的第一行相对导入,如前所述,这是from .. import module1

您需要将外部模块的父目录的路径包含在PYTHONPATH环境变量中,然后您可以在任意位置使用第一个脚本中使用的命令。

PYTHONPATH是python搜索你试图导入的任何模块的地方:

 #!/bin/bash export PYTHONPATH=$PYTHONPATH:PATH/TO/MODULE/PARENTDIR python -m outer_module.inner_module.myscript $@ 

正如错误信息所示:

 ValueError: Attempted relative import in non-package 

解决这个问题的方法是创建一个包,并让脚本在其路径中执行该包。

你已经有了一个包,因为你在这些目录中有__init__.py文件; 但正如你所提到的那样,当你从项目目录中调用它的时候,你只能在你的路径中找到这个包。 那是因为. 在你的Python路径默认情况下。

要解决这个问题,只需将项目目录添加到你的Python路径,然后用python -m outer_module.inner_module.myscript调用它:

 #!/bin/bash export PYTHONPATH=$PYTHONPATH:$(dirname "$BASH_SOURCE")/../.. python -m outer_module.inner_module.myscript $@