Change directory of a parent process from a child process

ghz 昨天 ⋅ 2 views

I've created a cool python program that helps people navigate to other directories in an interactive way. When they get there I'd like to have them hit Enter and exit the program leaving them in the selected dir. However, you always end up in the same dir you started in b/c only the child process that python's running in actually changes directories and the parent process' directory remains unchanged.

Answer

The issue you're facing is due to the way Python handles the working directory in subprocesses. When you change the directory within the Python script, it only affects the child process (the Python process itself). Once the script exits, the parent shell (the terminal or command prompt that launched the script) retains its original working directory.

To solve this, you need to change the working directory in the parent shell. One way to achieve this is to exit the Python script and then use a shell command to change the directory in the parent process. Here's a workaround using os and sys:

Solution 1: Using os and sys

You can try launching a subprocess or using os to change the directory:

import os
import sys

def change_directory():
    new_dir = input("Enter the directory you want to navigate to: ")
    try:
        os.chdir(new_dir)  # Change to the new directory
        print(f"Changed to {new_dir}")
    except FileNotFoundError:
        print(f"Directory '{new_dir}' not found.")
    
    input("Press Enter to exit...")  # Wait for the user to press Enter
    sys.exit()  # Exit the program

change_directory()

Solution 2: Modify the Shell Directly

If you want to change the parent process's working directory (in the terminal or command prompt), you can invoke a shell command from Python:

  • For Linux/macOS:

    import os
    import sys
    import subprocess
    
    def change_directory():
        new_dir = input("Enter the directory you want to navigate to: ")
        try:
            subprocess.call(f"cd {new_dir}", shell=True)
            print(f"Changed to {new_dir}")
        except FileNotFoundError:
            print(f"Directory '{new_dir}' not found.")
    
        input("Press Enter to exit...")  # Wait for user to press Enter
        sys.exit()  # Exit Python script
    
    change_directory()
    
  • For Windows (using cmd):

    import os
    import sys
    import subprocess
    
    def change_directory():
        new_dir = input("Enter the directory you want to navigate to: ")
        try:
            subprocess.call(f"cd /d {new_dir}", shell=True)
            print(f"Changed to {new_dir}")
        except FileNotFoundError:
            print(f"Directory '{new_dir}' not found.")
    
        input("Press Enter to exit...")  # Wait for user to press Enter
        sys.exit()  # Exit Python script
    
    change_directory()
    

In both cases, the subprocess.call will execute the cd command in the shell, but it still won't affect the terminal's directory. To make it work, you'd need to launch the Python script from the terminal and then use a shell script or terminal wrapper that modifies the shell environment.