2014-11-04 104 views
3

我有一个Python脚本,说myscript.py,使用相对模块导入,即from .. import module1,在我的项目布局如下:如何运行从任何位置调用Python脚本的Bash脚本?

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 [email protected] 

这工作执行myscript.py并根据需要将参数转发给我的剧本,但是当我打电话./outer_module/inner_module/myscript.shproject DIRECTO内它只能如上所示。

如何让这个脚本可以在任何地方工作?例如,我如何让这项工作拨打电话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 [email protected] 

当我执行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

+1

尝试:'(CD $ && SCRIPTDIR蟒蛇./devicelist.py $ @)' – ryanpattison 2014-11-04 23:55:50

+1

你的工作目录必须是'outer_module'所在的目录,而不是'outer_module'本身;否则'outer_module'不是一个包(因此是例外)。 (这很难做得太精确,因为你似乎已经在问题的中途切换了所有的名字,但是如果你在'inner_module'里面,那就是同样的问题。) – abarnert 2014-11-04 23:59:15

+1

或者,您只需不要在这些目录的_any_中,并在运行脚本之前设置'PYTHONPATH = ''。 – abarnert 2014-11-05 00:00:11

回答

2

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

PYTHONPATH就是对于任何模块蟒蛇搜索尝试导入:

#!/bin/bash 
export PYTHONPATH=$PYTHONPATH:PATH/TO/MODULE/PARENTDIR 
python -m outer_module.inner_module.myscript [email protected] 
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 [email protected]