14

What's the best way to pass bash variables to a python script. I'd like to do something like the following:

$cat test.sh
#!/bin/bash

foo="hi"
python -c 'import test; test.printfoo($foo)'

$cat test.py
#!/bin/python

def printfoo(str):
    print str

When I try running the bash script, I get a syntax error:

  File "<string>", line 1
    import test; test.printfoo($foo)
                               ^
SyntaxError: invalid syntax

5 Answers 5

14

You can use os.getenv to access environment variables from Python:

import os
import test
test.printfoo(os.getenv('foo'))

However, in order for environment variables to be passed from Bash to any processes it creates, you need to export them with the export builtin:

foo="hi"
export foo
# Alternatively, the above can be done in one line like this:
# export foo="hi"

python <<EOF
import os
import test
test.printfoo(os.getenv('foo'))
EOF

As an alternative to using environment variables, you can just pass parameters directly on the command line. Any options passed to Python after the -c command get loaded into the sys.argv array:

# Pass two arguments 'foo' and 'bar' to Python
python - foo bar <<EOF
import sys
# argv[0] is the name of the program, so ignore it
print 'Arguments:', ' '.join(sys.argv[1:])
# Output is:
# Arguments: foo bar
EOF
Sign up to request clarification or add additional context in comments.

Comments

10

In short, this works:

...
python -c "import test; test.printfoo('$foo')"
...

Update:

If you think the string may contain single quotes(') as said by @Gordon in the comment below, You can escape those single quotes pretty easily in bash. Here's a alternative solution in that case:

...
python -c "import test; test.printfoo('"${foo//\'/\\\'}"');"
...

1 Comment

This will fail interestingly if $foo contains any single-quotes or other characters python interprets inside literals. @Adam's solution is more robust...
3

Do it with argv handling. This way you don't have to import it then run it from the interpreter.

test.py

import sys

def printfoo(string):
    print string

if __name__ in '__main__':
    printfoo(sys.argv[1])

python test.py testingout

1 Comment

I was hoping to call printfoo directly because I have a lot of other python functions that take arguments, which need to be called from bash. If I go through main for all of them, it would be more complex.
1

You have to use double quotes to get variable substitution in bash. Similar to PHP.

$ foo=bar
$ echo $foo
bar
$ echo "$foo"
bar
$ echo '$foo'
$foo

Thus, this should work:

python -c "import test; test.printfoo($foo)"

2 Comments

That gets further, but now there's an error on the python side, where it says NameError: name 'hi' is not defined.
Can't edit, but for anyone looking at this and the comment above me, the answer is to put $foo in single quotes in the python segment, since otherwise it'll just be read as undefined variable name bar, hence the NameError. So python -c "import test; test.printfoo('$foo')", now you'll be printing the string 'bar' as desired.
0

If you use single quotes(') after python -c You can use '"' around environment variable

#!/bin/bash
python -c 'import test; test.printfoo('"'$foo'"')'

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.