0

I imagine this question has been asked before, however I could not find a previous question regarding this.

So let's say I have a python script helloPython.py, which prints something. Now I want to call that script from within a bash script, which can be done like this. All good so far.
However, the right python path isn't necessarily always the first python executable as found in PATH, so I declare a global variable containing a default path and have a read in function to enable the user to give a custom path to a python executable.

To elaborate, this is my code:

#!/bin/bash
PYTHON="/usr/bin/python" #default address

function helloPython {
    return PYTHON helloPython.py;
}

function readin {
    ## Read in the options
    for i in "$@"
    do
    case $i in
        -p=*|--python=*)
        PYTHON="${i#*=}"
        shift
        ;;
        *)

        ;;
    esac
    done
}

readin
helloPython

This gives: "return: PYTHON: numeric argument required" Alternatively, return $(PYTHON helloPython.py); gives "PYTHON: command not found" and return $($(PYTHON) checkPythonVersion.py); gives "PYTHON: command not found \n checkPythonVersion.py: command not found"

So now my question is: How can I use the global variable PYTHON in such a way that I can execute the python script from within bash?

Community
  • 1
  • 1
Simon Klaver
  • 480
  • 5
  • 24
  • As an aside, you have no *non*-global variables here. Even `i` is global, and different after you ran `readin` than it was before. To have a local in bash, you need to explicitly declare it: `local i` or `declare i` inside your function, before assigning to it. – Charles Duffy Apr 17 '17 at 15:58
  • (I would also suggest having your default Python interpreter just be `python`, so that it honors the locally configured PATH, rather than hardcoding `/usr/bin`). – Charles Duffy Apr 17 '17 at 15:59
  • You can only return an integer between 0 (zero) and 255 from a function in Bash. – cdarke Apr 17 '17 at 16:21

2 Answers2

1

You can simplify your script :

#!/bin/bash
PYTHON="/usr/bin/python"
for i in "$@"
do
  case $i in
    -p=*|--python=*)
      PYTHON="${i#*=}"
      shift
      ;;
  esac
done
"$PYTHON" helloPython.py

A few notes :

  • Your initial script was using "$@" in the readin function, but was calling this function without providing arguments. In cases like these, you should write the command in the following way to allow all arguments from the calling context to be passed as is : readin "$@"
  • Using a function to perform a single command while using variables inherited from the calling context is technically valid, but adds some complexity which may be preferable to avoid unless it is a function that will be reused.
Fred
  • 6,590
  • 9
  • 20
0

don't return, just execute the command:

helloPython() {
    "${PYTHON}" helloPython.py;
}

return tells the function's own exit code, it's not what you need in this case.

odradek
  • 993
  • 7
  • 14
  • 1
    `function helloPython` is a non-POSIX-compliant function declaration syntax -- it isn't guaranteed to work with `#!/bin/sh` shebangs, or otherwise with any non-extended shell. Better to use the portable syntax: `helloPython() {` with no `function` preceding. – Charles Duffy Apr 17 '17 at 15:56
  • indeed. i just addressed the main issue here, i updated my answer nonetheless. – odradek Apr 17 '17 at 16:10