6

Is there any way to call a shell script and use the functions/variable defined in the script from python?

The script is unix_shell.sh

#!/bin/bash
function foo
{
...
}

Is it possible to call this function foo from python?

Solution:

  1. For functions: Convert Shell functions to python functions
  2. For shell local variables(non-exported), run this command in shell, just before calling python script:
    export $(set | tr '\n' ' ')

  3. For shell global variables(exported from shell), in python, you can: import os print os.environ["VAR1"]

Neerav
  • 1,399
  • 5
  • 15
  • 25

6 Answers6

6

Yes, in a similar way to how you would call it from another bash script:

import subprocess
subprocess.check_output(['bash', '-c', 'source unix_shell.sh && foo'])
Eric
  • 95,302
  • 53
  • 242
  • 374
3

This can be done with subprocess. (At least this was what I was trying to do when I searched for this)

Like so:

output = subprocess.check_output(['bash', '-c', 'source utility_functions.sh; get_new_value 5'])

where utility_functions.sh looks like this:

#!/bin/bash
function get_new_value
{
    let "new_value=$1 * $1"
    echo $new_value
}

Here's how it looks in action...

>>> import subprocess
>>> output = subprocess.check_output(['bash', '-c', 'source utility_functions.sh; get_new_value 5'])
>>> print(output)
b'25\n'
1

No, that's not possible. You can execute a shell script, pass parameters on the command line, and it could print data out, which you could parse from Python.

But that's not really calling the function. That's still executing bash with options and getting a string back on stdio.

That might do what you want. But it's probably not the right way to do it. Bash can not do that many things that Python can not. Implement the function in Python instead.

Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251
1

With the help of above answer and this answer, I come up with this:

import subprocess
command = 'bash -c "source ~/.fileContainingTheFunction && theFunction"'
stdout = subprocess.getoutput(command)
print(stdout)

I'm using Python 3.6.5 in Ubuntu 18.04 LTS.

M Imam Pratama
  • 998
  • 11
  • 26
0

I do not know to much about python, but if You use export -f foo after the shell script function definition, then if You start a sub bash, the function could be called. Without export, You need to run the shell script as . script.sh inside the sub bash started in python, but it will run everything in it and will define all the functions and all variables.

TrueY
  • 7,360
  • 1
  • 41
  • 46
0

You could separate each function into their own bash file. Then use Python to pass the right parameters to each separate bash file.

This may be easier than just re-writing the bash functions in Python yourself.

You can then call these functions using

import subprocess
subprocess.call(['bash', 'function1.sh'])
subprocess.call(['bash', 'function2.sh'])
# etc. etc.

You can use subprocess to pass parameters too.

Cephlin
  • 176
  • 2
  • 12