1

I have a search program that helps users find files on their system. I would like to have it perform tasks, such as opening the file within editor or changing the parent shell directory to the parent folder of the file exiting my python program.

Right now I achieve this by running a bash wrapper that executes the commands the python program writes to the stdout. I was wondering if there was a way to do this without the wrapper.

Note: subprocess and os commands create a subshell and do not alter the parent shell. This is an acceptable answer for opening a file in the editor, but not for moving the current working directory of the parent shell to the desired location on exit.

An acceptable alternative might be to open a subshell in a desired directory

example

#this opens a bash shell, but I can't send it to the right directory
subprocess.run("bash")
jsbueno
  • 99,910
  • 10
  • 151
  • 209
jeffpkamp
  • 2,732
  • 2
  • 27
  • 51
  • Why not use `os.system()` or (preferably) `subprocess.run()`? – MattDMo Feb 16 '23 at 17:45
  • 1
    @MattDMo Both execute commands in a subshell not the the parent shell. – GIZ Feb 16 '23 at 17:48
  • this would work for opening the file in an editor, but I don't think they would work to take the user to the directory. – jeffpkamp Feb 16 '23 at 17:48
  • I believe this is not possible. Stay with your wrapper. – Marcus Vdt Feb 16 '23 at 17:53
  • See the duplicate I just tagged. It should work, however it may be simpler to keep your wrapper if there's no overwhelming reason to *not* use it. – MattDMo Feb 16 '23 at 17:57
  • 1
    @MattDMo this isn't really a duplicate of that question as that is asking how to replicate the BASH `exec` command with all arguments supplied to the program. I'm not looking to run an executable but instead to run a shell command in the parent shell. for example, I tried `os.execv("/usr/bin/cd",["~"])` and it didn't work. – jeffpkamp Feb 16 '23 at 18:07
  • _changing the directory of the parent folder of the file_ This makes no sense. Did you mean "change the **current directory** of the **parent process**"? – John Gordon Feb 16 '23 at 18:13
  • OK, I reopened it. I suggest putting your last comment in the question itself as additional info on what you've tried. – MattDMo Feb 16 '23 at 18:13
  • @JohnGordon sorry that was a typo. I meant to change the parent shell directory to the directory containing the file indicated by the user. – jeffpkamp Feb 16 '23 at 18:16
  • I'm not sure if I'm sending you on a wild goose chase or not (and it would be pretty difficult if it is even possible), but if you only need to run in linux and don't mind some elevated priviges. you could look into modifying the code/memory of the enclosing bash process using ptrace? – Oli Feb 16 '23 at 18:23
  • What would it do with other shell types (e.g. bash, zsh, fish, etc)? I think it's for this reason that virtualenv uses a set of shell specific scripts to accomplish what you're after – Sam Mason Feb 16 '23 at 18:41
  • @SamMason this is partially why I was after a python specific answer. Essentially all of the people I am writing this for will be in Bash, but are we really programmers if we don't try and catch the edge cases? – jeffpkamp Feb 16 '23 at 18:46
  • it appears that the easiest way to do this will be to stick with my wrapper script or to use something like this to open a subshell in the given directory. `subprocess.run("(cd /path/to/file && bash",shell=True)` – jeffpkamp Feb 16 '23 at 18:55

1 Answers1

0

This, if doable, will require quite a hack. Because the PWD is passed from the shell into the subprocess - in this case, the Python process, as a subprocess owned variable, and changing it won't modify what is in the super program.

On Unix, maybe it is achievable by opening a detachable sub-process that will pipe keyboard strokes into the TTY after the main program exits - I find this the most likely to succeed than any other thing.

jsbueno
  • 99,910
  • 10
  • 151
  • 209