-- Leo's gemini proxy

-- Connecting to thrig.me:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

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:


interface - the parent process could have an interface or API that the child could call, e.g. via a pipe that the child could write chdir commands into, or maybe it evals the contents of some known file under some known condition.

bug - the child maybe could exploit a bug in the parent process that lets the child execute a suitable chdir call.

debugger - the child could run gdb(1) or similar and use that to execute a chdir call in the parent process.


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

-- Response ended

-- Page fetched on Tue May 21 17:40:03 2024