💾 Archived View for thrig.me › blog › 2023 › 06 › 11 › chdir-parent-process.gmi captured on 2024-08-31 at 12:13:15. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-11-14)

-=-=-=-=-=-=-

Can a child process affect the working directory of the parent process?

No.

Elaboration

A not uncommon question claims that some bit of code "does not work",

    chdir "/home/someuser";

and continues to "not work" after proper error checking has been added:

    chdir "/home/someuser" or die "Aaaaaaaaaaargh: $!";

Usually what the asker has done is something like the following, to run chdir under some program under their shell.

    $ cd /
    $ perl -e 'chdir "/tmp" or die "chdir $!"'
    $ pwd
    /

See? Doesn't work!™

In this case the perl process did chdir, but then that process went away, and the parent shell process is still in the same working directory as it was before the command. A child process is completely separate from the parent, and cannot affect the working directory of the parent.

    $ cd /
    $ perl -e 'chdir "/tmp" && exec "pwd"'
    /tmp
    $ pwd
    /
    $ ( cd /tmp && pwd )
    /tmp
    $ pwd
    /

Complications

The previous statement is something of a falsehood. File descriptors can be shared between processes, so a child is often mostly separate from the parent. A child process could modify the working directory of the parent process in various ways:

The last option used to work, and was handy if someone left a shell open on a NFS mount and you wanted to move their shell elsewhere. However, these days debuggers generally are under security restrictions that prevent such shenanigans from a child process.

So how do you chdir in the parent process?

You run chdir in the parent process. cd is a shell builtin for that reason.

    $ cd `perl -e 'print "/tmp"'`

But that's pretty silly, unless you have some complicated command for where the shell needs to chdir to. More common is a wrapper program that runs a new shell in a particular directory:

    $ pwd
    /
    $ echo $
    7107
    $ cpanm --look Mojo
    ...
    $ pwd
    /home/jmates/.cpanm/work/1686443738.9173/Mojolicious-9.32
    $ echo $
    59851
    $ exit
    $ pwd
    /
    $ echo $
    7107

However, that new shell may not have the history or such of the parent shell process, depending on the shell, its configuration, and exactly what the wrapper program does to launch the new shell.

The best way to learn this is to write your own shell, in which case it may quickly become apparent that the chdir must happen within that shell. I'm pretty sure "Advanced Programming in the Unix Environment" covers this at some point.

tags #unix