Adobe
Adobe

Reputation: 13477

Python: substitution in subprocess call

I do for in range(...):, and I need to substitute i in a subprocess call. I tried to do it like this:

myStr = "'(insert \"%g\")'" %i
    subprocess.Popen(["emacs", "--batch", "+83:28", "md.mdp", "--eval", 
                      eval("myStr"), "-f", "save-buffer", "--kill"], 
                     stdout=subprocess.PIPE).wait()

and like this:

subprocess.Popen(["emacs", "--batch", "+83:28", "md.mdp", "--eval", 
                  "'(insert \"%g\")'" %i, "-f", "save-buffer", "--kill"], 
                 stdout=subprocess.PIPE).wait()

and also like this:

subprocess.Popen(["emacs", "--batch", "+83:28", "md.mdp", "--eval", 
                  ("'(insert \"%g\")'" %i), "-f", "save-buffer", "--kill"], 
                 stdout=subprocess.PIPE).wait()

But none of these work. Can You help me to make it alright?

Also - is that true - that when system("bash command") wouldn't wait?

Edit:

It is for script to run a computer simulation for various value of a given parameter. It copies the baseData dir for each run, goes there, changes the parameter file (inserts the value), then it should run a simulation and go back.

This doesn't produce error - but also doesn't insert the value of i in the md.mdp:

myStr = "'(insert \"%g\")'" %i
subprocess.Popen(["emacs", "--batch", "+83:28", "md.mdp", "--eval", 
                  myStr, "-f", "save-buffer", "--kill"], 
                 stdout=subprocess.PIPE).wait()

nor this helps:

myStr = "'(insert \\\"%g\\\")'" %i

The following variants also do not insert a thing:

subprocess.Popen(["emacs", "--batch", "+83:28", "md.mdp", "--eval", 
              "'(insert \"%g\")'" %i, "-f", "save-buffer", "--kill"], 
             stdout=subprocess.PIPE).wait()

subprocess.Popen(["emacs", "--batch", "+83:28", "md.mdp", "--eval", 
              ("'(insert \"%g\")'" %i), "-f", "save-buffer", "--kill"], 
             stdout=subprocess.PIPE).wait()

Upvotes: 0

Views: 728

Answers (2)

Adobe
Adobe

Reputation: 13477

The following works:

subprocess.Popen(["emacs", "--batch", "+83:28", "md.mdp", "--eval", 
                 eval("'(insert \"%g\")'" %i), "-f", "save-buffer", "--kill"], 
                 stdout=subprocess.PIPE).wait()

Edit 1:

And some times You don't need to eval:

subprocess.Popen(["grompp", "-f", "%s" %opts.myMdp, "-c", "%s" %opts.myGro,
                 "-p", "%s" %opts.myTop], stdout=subprocess.PIPE).wait()

Edit 2:

When I do '(insert \"%g\")' %i it gives

Traceback (most recent call last): File
"/home/boris/its/plts/bio/bk-simulates-work.py", line 100, in <module>

subprocess.Popen(["emacs", "--batch", "+83:28", "md.mdp", "--eval",
'(insert \"%g\")' %i, "-f", "save-buffer", "--kill"],
stdout=subprocess.PIPE).wait() 

NameError: name 'i' is not defined

While it actually is defined, since the command is inside of for in in range.....

And when I do '(insert \"%g\")':

subprocess.Popen(["emacs", "--batch", "+83:28", "md.mdp", "--eval",
'(insert \"%g\")', "-f", "save-buffer", "--kill"],
stdout=subprocess.PIPE).wait()

it just inserts %g.

Actually I don't do it (inserting a i in a particular place in a file) with emacs any more:

myInput = open(opts.myMdp, 'r')
myTempFile = opts.myMdp + '~~~'
myOutput = open(myTempFile, 'w')
for line in myInput:
    myOutput.write(line.replace(opts.myToken, "%g" %myValue))
myOutput.close()
myInput.close()
os.rename(myTempFile, opts.myMdp)

Upvotes: 0

jcollado
jcollado

Reputation: 40394

I'd say that the problem is that you don't need to quote the insert statement part. The reason for this is that you use quotes in a shell to make it clear that the string between quotes is to be passed as a single argument.

However, in subprocess.Popen you're using an array to perform the same functionality, so the quotes are not needed. In other words, in a shell quotes aren't passed to the process being launched and, in the subprocess.Popen call, they are being passed.

Upvotes: 1

Related Questions