How to change environmental variable of external shell?

I want to write a program (ideally in Rust, but if – as it appears from my internet searches – this is impossible I will begrudgingly do it in bash script) that automatically cds into a newly created directory. std::env::set_current_directory just sets it for the current program, not for the outer shell from which I called the program.

If it matters: I'm using Debian and Zsh.

You can't change the working directory of the invoking shell. That's process separation thing, not a language specific thing. It would be very security unfriendly.

(Same goes for environment variables.)

1 Like

Is there no way to configure the shell maybe to allow something like that?

But thanks for the answer anyway!

It would be something at the OS level, not the shell level.

Here's a thread showing how to do it by attaching a debugger to the parent process.

Like many in the thread say, it's a hack and ill advised. Don't be surprised if weird unpleasantness results.

1 Like

Oh and for actual environment variables it's UB, as you'd be changing them in a multithreaded context. Unsure if it's straight-up UB for the working directory or not.

1 Like

Really funny case where what you need is absolutely different from what you ask for.

As in:

  • What you ask for is impossible to do, and @quinedot is 100% correct.
  • What you need is, actually, easily doable, not hard at all.

You can look on how Midnight Commander does that in Debian. If you install that package you'll find out that it does what you need.

How? It't not too hard, really. It adds alias to your shell and now, when you run mc command you are not running binary directly, but you are running small shell script. That script executes actual Midnight Commander binary with a special parameter and then changes the directory in your shell (bash, csh, zsh, etc) on behalf of Midnight Commander.

The end result: it looks as if everything magically works like you want it to work, even if Midnight Commander, itself, never changes the directory of your shell.

Midnight Commander is written in C, but the whole thing is so simple that it can be easily replicated in Rust.


In addition, there is a Bash construct that will run a program and execute the output in the current shell context. That would be:

eval "$(./my-program)"

So you could write my-program in Rust and have it output something like:

cd mydir

then that would execute in the shell. The user just has to remember to call it that way. This is a security feature, so that the user would know that shenanigans like this will happen and is prepared for it.


This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.