0

When running a PowerShell script from bash, is there a way to have PowerShell set the current directory of the calling shell up exit?

I have tried the following things (independently, not all at once)

#!/usr/bin/env pwsh 
# myscript.ps1

$desiredPath = "/the/path/I/Want"
& cd $desiredPath
& Set-Location $desiredPath
& zsh -c 'cd ${clonePath}'

Unfortunately, the end result always ends up being back at the prior $PWD.

I am sure I could return the path from the script and then pipe it to another command, but I am trying to find out if there is a way to accomplish this without having to do that, as I have the scripts folder on my path so I can simply call myscript.ps1 arg1 arg2.

MostHated
  • 151
  • 2
  • 11
  • 2
    this is not possible. the ps1 script runs in its own process which cannot impact env vars of its parent process. – pynexj Mar 16 '21 at 04:09

2 Answers2

1

There is no way for a subprocess to modify the environment of its parent process without cooperation from the parent; but if you can get the parent to cooperate, you can pass back an expression for it to evaluate.

(I'm not very conversant in PowerShell so I am putting a simple Python script here instead; but you should easily see how to replace it with PowerShell.)

cd "$(python -c 'print("/tmp/fnord")')"

or more generally

eval $(python -c 'print("cd /tmp/fnord")')

but you really should avoid eval in most circumstances if at all feasible, and then make really sure you can completely trust its output if you can't avoid it.

Needless to say, the subprocess could do something a lot more complex, as long as it prints the expression you want to pass back to the parent (and nothing else) to standard output during its execution.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • I appreciate the reply. It gave me an idea to make an alias with an inline function which keeps it at a single command and an argument, but gives me the ability to take the scripts output at the end and apply a `cd` to it. `alias clone='f() { cd $(clone.ps1 $1) };f'` – MostHated Mar 17 '21 at 15:44
  • 1
    If that's a shell function, you want to supply double quotes around the argument to `cd`; see also [When to wrap quotes around a shell variable?](https://stackoverflow.com/questions/10067266/when-to-wrap-quotes-around-a-shell-variable) I don't think there are any sane reasons to wrap the function in an alias; just call the function `clone` and be done with it. See further https://stackoverflow.com/questions/57239089/why-would-i-create-an-alias-which-creates-a-function – tripleee Mar 17 '21 at 18:03
  • I definitely see your point there. I had come across something someone else had done like that, tried it, saw that it worked, and then didn't think much else of it. I can certainly now see how it is a bit unecessary. – MostHated Mar 17 '21 at 22:28
1

You can have a script before calling other scripts, which sets up the environment for the PowerShell session window temporarily while this window is still open running the scripts you would like to run. With environment variables to be set temporarily in the PowerShell session, and to change the $PWD variable, and then afterwards the file would call each of the scripts and should keep the $PWD after the first script was run and finishes, and the script to run after.

Shaqil Ismail
  • 1,794
  • 1
  • 4
  • 5