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

时间:2014-11-04 23:52:08

标签: python linux bash shell

我有一个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并根据需要将参数转发到我的脚本,但它仅在我从上面显示的./outer_module/inner_module/myscript.sh目录中调用project时才有效。

如何让这个脚本可以在任何地方运行?例如,如何才能使此功能适用于bash /root/to/my/project/outer_module/inner_module/myscript.sh之类的调用?

以下是我的尝试:

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

#!/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

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:2)

正如错误消息所示:

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 $@