views:

134

answers:

3

I'm working on a simple Python script that can use subprocess and/or os to execute some commands, which is working fine.

However, when the script exits I'd like to cd the actual Terminal (in this case OS X) so on exit, the new files are ready to use in the directory where the have been created. All the following (subprocess.Popen, os.system, os.chdir) can do what I want from within the script (i.e. they execute stuff in the target directory) but on exit leave the Terminal at the script's own directory, not the target directory.

I'd like to avoid writing a shell script to temporary file just to achieve this, if this is at all possible anyway?

A: 

Have you tried simply running the program in the current shell?

i.e

$. script.py

instead of

$script.py

Paul Creasey
yes, and no - same problem, but thanks!
Dave Everitt
You can't run a **non-shell** script in the current shell. The dot prefix makes no difference in this case.
ΤΖΩΤΖΙΟΥ
+4  A: 

Sadly, no. Processes are not allowed to change the environment of their parent process, and in this case your Python script is a child process of the shell. You could "fake" it by having your Python process set up a new shell - call subprocess to open a shell process and present it to the user, inheriting the modified environment from itself - but that has the downside of forcing the Python process to run continually.

This is really what shell scripts are for.. :-) Someone clearly needs to write a more traditional shell (e.g. closer to Bash than IPython) which can use python as its scripting language.

Nick Bastin
Thanks - I'll rewrite is as a shell script, and call the Python from there instead :-)
Dave Everitt
You don't need to leave the Python interpreter hanging around. You just need to get the process environment the way you want it (e.g. `os.chdir()`) and then `os.execv()` a new shell. Yes, you'll still have a subordinate shell running, but the Python interpreter will have been replaced. http://docs.python.org/library/os.html#os.execv
msw
@msw: I've never been able to reliably pull that off on all platforms with shells in particular (specifically powershell), but I should have suggested that.
Nick Bastin
+2  A: 

Forgetting Python for the moment, no subprocess can change the state of its invoking shell. Thus you need a construct which alters the state of the calling shell which is what Paul Creasey was hinting at.

alias mycd="cd `echo $1`"

where echo could be replaced with script_which_outputs_a_directory_name_on_stdout.py It's kind of a hack, but at least it's an old hack.

msw
I see what you mean; however (if I don't rewrite is as a shell script), I think I'll print 'cd [path_to_dir]' at the end so it can just be copied to the command line!
Dave Everitt