Python – How do I run a Bash script that calls a Python script from anywhere?

How do I run a Bash script that calls a Python script from anywhere?… here is a solution to the problem.

How do I run a Bash script that calls a Python script from anywhere?

I have a Python script, like myscript.py, which uses relative module imports, i.e. from: import module1, and my project layout is as follows:

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

I have a Bash script, like myscript.sh, which is a wrapper for my python script as follows:

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

This does myscript.py and forwards parameters to my script as needed, but it only works when I call ./outer_module/inner_module/myscript.sh from the project directory shown above.

How can I get this script to run anywhere? For example, how can I make it work for calls like bash/root/to/my/project/outer_module/inner_module/myscript.sh?

Here is my attempt :

When executing myscript.sh from anywhere else, I get the error: No module named outer_module.inner_module. Then I tried another way to execute a bash script from anywhere by replacing myscript.sh with:

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

When I execute myscript.sh as shown above, I get the following information:

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

This is due to the relative import of the first line in the myscript.py, as mentioned earlier, i.e. from: import module1.

Solution

YOU

NEED TO INCLUDE THE PATH TO THE EXTERNAL MODULE’S PARENT DIRECTORY IN THE PYTHONPATH ENVIRONMENT VARIABLE, AND THEN YOU CAN USE THE SAME COMMAND YOU USED IN THE FIRST SCRIPT FROM ANYWHERE.

PYTHONPATH IS WHERE PYTHON SEARCHES FOR ANY MODULE YOU ARE TRYING TO IMPORT:

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

Related Problems and Solutions