Reputation: 171167
I have a Python program which needs to execute a different process (I use subprocess.Popen
for that). I need this execution to behave as if the following was typed by the user on the shell command prompt:
$ source path/to/some_file
$ ./some_program
I expect I will use shell=True
and some form of command chaining to first run source
and then execute the program. However, I am facing the following problem:
The shell which launches my Python program could be bash
, sh
, tcsh
(or maybe some other flavour of csh
). I need to source a different some_file
based on which shell is running. Is there a way to determine this? Either in Python or by running something inside Popen(..., shell=True)
, both would do.
I was considering writing some sort of "shell polyglot" to get different output from different shells, but my shell skills (especially in csh) aren't up to such a task. What options do I have?
Upvotes: 0
Views: 120
Reputation: 249502
Which shell is used by subprocess.Popen()
is not determined by the parent shell used to launch Python. Rather, the shell used by Python is always /bin/sh
by default, and you can change it if you need by explicitly specifying an executable in Popen()
.
But really, any given shell script can be written for one specific type of shell. Let's say it's bash
. Then you can simply ignore these details on the Python side by writing a shell script like this:
#!/usr/bin/env bash
source path/to/some_file
exec ./some_program
There you go: a complete launcher script which switches to bash at the start, sources the necessary bits, and launches your program. Any reasonable shell should be able to run it, so now you needn't worry about exactly which shell Python invokes...plus you have a more repeatable way to launch your program outside of Python.
Upvotes: 3
Reputation: 6777
..what about spawning the shell and then communicating with it?
I mean, something like this:
proc = subprocess.Popen(['/bin/bash'], stdin=PIPE, stdout=PIPE)
proc.communicate("source path/to/some_file\n"
"./some_program\n")
Since you want to execute a two commands inside a specific shell, I think this would be the best solution you have.
Otherwise, you might find that your shell accepts arguments such as an "init script" and "initial command"; in this case, and if you only need to use that specific shell, you should use them; for example, bash accepts --init-file file
and -c command
that would do the job (--init-file
will be loaded instead of bashrc).
Upvotes: 1