1

I'm trying to figure out if it is possible to pass values stored in a variable in Bash in as argument values in a python script.

We have a python script that we use to create DNS records in BIND and I've been tasked with cleaning up our outdated DNS database. so far I have something like this in bash:

HOSTNAMES=$(</Users/test/test.txt)

ZONE="zone name here"

IP=$(</Users/test/iptest.txt)

for host in $HOSTNAMES
do
  python pytest.py --host $HOSTNAMES --zone $ZONE --ip $IP
done

Unfortunately, I don't have a test environment where I can test this on before I run it on prod and I don't have any experience with Python or Bash scripting. I've mainly only done Powershell scripting, but was wondering if something like what I have above would work.

I've looked around on the forums here but have not found anything that I could make sense of. This post seems to answer my question somewhat, but I'm still not completely sure how this works. How to pass a Bash variable to Python?

Community
  • 1
  • 1
Niag Ntawv
  • 197
  • 1
  • 4
  • 16
  • 1
    It should yes. Don't see why something like this wouldn't work. – Torxed Jun 01 '16 at 21:16
  • 1
    Change 'python' to 'echo' and see what prints out. – Marichyasana Jun 01 '16 at 21:19
  • 1
    Aside: All-caps variable names are bad form. See POSIX conventions at http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html -- fourth paragraph -- which specifies the namespace of **lowercase** variables as reserved for application use. Using upper-case variables in your applications means you can override a variable with meaning to the shell or system by mistake. – Charles Duffy Jun 01 '16 at 21:19
  • 1
    @Marichyasana, better would be to `set -x` earlier, or to change `python` to `printf '%q\n'`. `echo`'s output is very often misleading. – Charles Duffy Jun 01 '16 at 21:20
  • 1
    @Marichyasana, ...for instance, you can't tell the difference between `echo cat "hello world"` and `echo cat "hello" "world"`, but they're very different commands. – Charles Duffy Jun 01 '16 at 21:20
  • @Charles Duffy good advice, thanks. – Marichyasana Jun 01 '16 at 21:22
  • 1
    ...re: `for host in $HOSTNAMES`, by the way, see http://mywiki.wooledge.org/DontReadLinesWithFor, and http://mywiki.wooledge.org/BashFAQ/001 for the better-practice alternative. – Charles Duffy Jun 01 '16 at 21:24
  • @CharlesDuffy Thanks for the links. I've looked at those previously as well. I don't remember why I changed it to a for loop but when I was originally just testing basic Bash commands for iteration I was using the while do method outlined in that article. – Niag Ntawv Jun 01 '16 at 21:32
  • I'd suggest extending your answer to provide a standalone reproducer per http://stackoverflow.com/help/mcve -- something folks can run to reproduce your problem without needing things like your `pytest` or `test.txt` or `iptext.txt`, all of which are required for the code given in the question to run. – Charles Duffy Jun 01 '16 at 21:36
  • ...see the answer by Diego as-amended, which is a good example of a reproducer: Inasmuch as it calls Python code, that Python code is right there in the answer (and is written to be as terse as possible, including only the minimum contents necessary for the demonstration); code included in a question should follow those same principals. – Charles Duffy Jun 01 '16 at 21:37

2 Answers2

4

Yes, seems to work just fine to me.

To test, I threw together a very quick python script called test.py:

#!/usr/bin/python
import sys

print 'number of arguments: ', len(sys.argv)
#we know sys.argv[0] is the script name, let's look at sys.argv[1]
print sys.argv[1]

Then, in your terminal, set a variable:

>testvar="TESTING"

And try your script, passing the variable into the script:

>python test.py $testvar
>number of arguments: 2
>TESTING

Admittedly I'm not very well-versed in Python, but this did seem to accomplish what you wanted. That said, this assumes the Python script you referenced is already set up to parse the names of the parameters being passed to it - you'll notice my test script does NOT do that, it simply spits out whatever you pass into it.

Brendan D.
  • 96
  • 7
  • this looks to be what I was after. Yes the real script is set to parse the parameters being passed in, I just wasn't sure if this was how it's done in bash and python. – Niag Ntawv Jun 02 '16 at 03:57
3

As long as the variables are exported, they're accessible from Python.

$ export VAR=val
$ python -c "import os; print os.environ['VAR']"
val
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Diego Torres Milano
  • 65,697
  • 9
  • 111
  • 134
  • Looks like he want to pass them to `sys.argv` tho? – Torxed Jun 01 '16 at 21:16
  • I don't think so. `HOSTNAMES`, `ZONE`, etc. look like env vars. – Diego Torres Milano Jun 01 '16 at 21:18
  • Except he's iterating over them, and passing them to `--host`? He just spelled the passed variable wrong – Torxed Jun 01 '16 at 21:19
  • @Torxed, ...spelled it wrong, or made a mistake in other code they didn't show (for instance, read it in inside a loop a la http://mywiki.wooledge.org/BashFAQ/024). – Charles Duffy Jun 01 '16 at 21:23
  • @DiegoTorresMilano I did see another post referencing what you said with regards to exporting the variables to make it accessible to python. I guess where the confusion was for me is would I be running something like, python pytest.py --host os.environ['HOSTNAME'] --zone os.environ['ZONE'] etc? Sorry, probably asking a lot of noob questions, but what does the -c option do? I looked at the man pages in my shell and it didn't have that option on there. – Niag Ntawv Jun 01 '16 at 21:37
  • @NiagNtawv, no, the `os.environ['HOSTNAME']` and `os.environ['ZONE']` code would be inside the Python file. `python -c 'python code here'` runs the code given on the command line, allowing a terse example that can be copied-and-pasted without needing a new file to run, but that `python code here` could also be contents of a `.py` file. – Charles Duffy Jun 01 '16 at 21:38