Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

After years of bash scripting I've been given the task of modifying a python script to have it call a shell script when certain conditions are met. That part wasn't too bad, but now I'm trying to also send this shell script a variable from within the python script and I'm getting lost.

The shell script takes stdin, which is where I'm trying to place the value of the python variable, which is just an interger.

my code (so far) looks like this:

if VAR > NUMBER:
import os
bashCommand = "echo something | /path/to/script --args"
os.system(bashCommand) 

and it works just fine. But what I am looking to do is make os.system(bashCommand) an equivalent of:

echo $VAR | /path/to/script --args

or even

echo 'some text' $VAR | /path/to/script --args

given the way os.system appears to work though it seems I'm approaching this completely wrong.

So I guess my question is how can I pass the value of VAR to bashCommand, preferably as stdin?

share|improve this question

3 Answers 3

up vote 1 down vote accepted

Python doesn't expand variables in strings in the same way as bash. If you have VAR in python and want to pass that to bash you could do

subprocess.call('echo {} | /path/to/script --args'.format(VAR), shell=True)

if VAR in python holds the name of a bash variable you want to expand you could do similar:

subprocess.call('echo "${}" | /path/to/script --args'.format(VAR), shell=True)
share|improve this answer
    
I'm not sure of the best-practice/security issues of using "shell=' but this worked for me. Marking resolved. –  kadamwolfe 23 hours ago

Calling os.system() is deprecated, though still valid. That functionality may be going away in the future (probably will be), so you might want to give serious consideration to refactoring those calls with the subprocess module, which has an very easy way to send data to a subprocess's STDIN and read from its STDOUT. https://docs.python.org/2/library/subprocess.html

share|improve this answer

Don't use os.system(), it is deprecated in favor of subprocess module.

In your case you can use subprocess module directly and its better to not use the shell=True parameter as this is not safe to run commands directly into the shell. All the functionalities you need here like pipe can be emulated by the subprocess module.

Lets take this example :

import subprocess
var = 'foobar'

first = subprocess.Popen(['/bin/echo', var], stdout=subprocess.PIPE)
second = subprocess.Popen(['bash', '/path/to/script', '--args'], stdin=first.stdout)

we have defined a varible var, then we have used the subprocess.Popen class to get the value of var using /bin/echo and then sent this value to the pipe. The first is an object of subprocess.Popen class.

Then we have used the STDOUT of first as STDIN of second via pipe and executed the bash script accordingly.

If you want to save the output of a command as a string use subprocess.check_output function instead e.g. :

second = subprocess.check_output(['bash', '/path/to/script', '--args'], stdin=first.stdout)

Read the offical documentation of subprocess module to get more idea.

share|improve this answer
    
This is great information and I think I could use it. The one thing I think I should mention though is that 'VAR' is a variable (integer) defined by the python script (that is to call the shell script) so we may not need to echo it, right? since python already knows its value. –  kadamwolfe yesterday
    
@kadamwolfe Yeah..you can use it directly then as I have used in the second object generation..I was just pointing out the processes in my sample script..fit it to meet your need :) –  heemayl yesterday
    
nice. so something like.... subprocess.Popen(['bash', '/path/to/script', '--args'], stdin="some text" VAR) ? –  kadamwolfe yesterday
    
@kadamwolfe I probably have misunderstood your point, you can't directly use a string as STDIN as it does not have fileno attribute..you can combine the two into a simple one liner: subprocess.Popen(['bash', '/path/to/script'], stdin=subprocess.Popen(['/bin/echo', var], stdout=subprocess.PIPE).stdout) ,if its a one time run then you can consider subprocess.call instead of subprocess.Popen.. –  heemayl yesterday
    
While I do appreciate the help, I'm not sure it resolves my issue. I'm checking if a variable's value is greater than another and if so, echo that variable's value to a shell script (preferably pre-pended by a text string. if VAR > NUMBER: <echo text string + VAR's value to /path/to/script --args> –  kadamwolfe yesterday

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.