views:

61

answers:

2

Hello, all,

I want to create a GUI python script to launch several processes. All of these processes originally were called by setting up a shell with a perl script (start_workspace.perl), and type the executable file name under the shell. inside, start_workspace.perl, it first set some ENV variables, and then call exec(/bin/bash), which launch the shell, so you can type "execfile" under the prompt to launch.

my problem, from my python script, I still want to use this shell (by subprocess.popen("perl start_workspace.perl")), but I do not want to be stopped to manually input "execfile". I want someway that I can specify the "execfile" at step of calling "start_workspace.perl", and the process can completed without any intervention.

something like command redirection. but I do not know if it is possible.

subprocess.popen(("perl start_workspace.perl") < "execfile")

+1  A: 

You are very close. In the subprocess documentation, see:

stdin, stdout and stderr specify the executed programs’ standard input, standard output and standard error file handles, respectively. Valid values are PIPE, an existing file descriptor (a positive integer), an existing file object, and None. PIPE indicates that a new pipe to the child should be created. With None, no redirection will occur; the child’s file handles will be inherited from the parent. Additionally, stderr can be STDOUT, which indicates that the stderr data from the applications should be captured into the same file handle as for stdout.

stdin, stderr, and stdout are named parameters for the popen method. You can open the input file and pass its file descriptor as stdin to your new process.

Matt Kane
hi, Matt, thank you so much for your answer. Do you mean that I could use the following: file=os.fdopen('./execfile'), then subprocess.popen("perl start_workspace.perl", stdin=file)?
pepero
I am not really a Python guy, but that seems reasonable.
Matt Kane
A: 

Using the subprocess module, it could be achieved this way. You can use the stdin stream to write your command to execute once the actual environment has been set.

start_workspace.perl

print "Perl: Setting some env variables\n";
$ENV{"SOME_VAR"} = "some value";
print "Perl: Starting bash\n";
exec('bash');

In python:

import subprocess 
p = subprocess.Popen( "perl start_workspace.perl", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
p.stdin.write('echo "Python: $SOME_VAR"\n')
p.stdin.write("make\n")
(stdoutdata, stderrdata) = p.communicate()
print stdoutdata
print stderrdata

Output is

Perl: Setting some env variables
Perl: Starting bash
Python: some value

make: *** No targets specified and no makefile found.  Stop.
Rod
I fixed your missing quote, but I think the question involves not giving the name of execfile to stdin, but the contents.
Matt Kane
hi, Rod, thank you very much for your answer. so you mean, the p.write("./execfile") can be as the input once shell has been launched? I will try and come back later. thanks again!
pepero
hi, I tried. unfortunately, this one does not work. the execfile I use is "make". make was not called.
pepero
@pepero Works with the updated code in my answer using make.
Rod
Hi, Rod, thank you so much for your follow up. It works now with your code. I find out if I use cmd= ["perl", "start_workspace.perl"], p = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE). It does not work.
pepero