0

I used to use Bash, which has this syntax:

VAR=VAL ./executable_file

to set VAR temporarily during the execution of executable_file.

Is there a corresponding syntax in pwsh?


PowerShell 7.4.0 on MS-Windows

7
  • Are you asking how to define an environment variable in PowerShell? 🤔 Commented Dec 2, 2023 at 10:21
  • @Olaf No. I can run $env:VAR=VAL to set an environment variable, but I need to unset it after execution (and it will cover the original value, which is not what I'm expecting). Commented Dec 2, 2023 at 10:23
  • 1
    You should update your question with additional information - do not add it as comment. If you don't make it permanent the variable will be gone when the PowerShell session ends. Or you save the value temprorarily to an intermediate variable and restore the original value later on. There is no shortcut for that in PowerSehll that I know of. Commented Dec 2, 2023 at 10:26
  • 1
    As of v7.4, PowerShell has no support for child process-scoped environment vars. (e.g., FOO=bar someutility …). [GitHub issue #3316] (github.com/PowerShell/PowerShell/issues/3316) is a request to support at least similar syntax. Current options: (a) Set env. vars. for the current process, call the child process (which inherits them), then restore the env. (b) Call via a shell (possible PowerShell itself) and set the vars. there - you pay a performance penalty. (c) In v7.4+, you may use Start-Process -NoNewWindow -Wait -Environment ... - you lose stream integration. Commented Dec 2, 2023 at 14:08
  • 1
    @mklement0 "... you lose stream integration." -- thx! I don't know this before. So I won't accept my answer because it is not perfect. Commented Dec 2, 2023 at 14:11

1 Answer 1

1

After consulting the relevant documents, I found that Start-Process -Environment @{VAR = VAL} --args ... can achieve this.

$TEEEST=40
$env:TEEEST=41
Start-Process -NoNewWindow -FilePath "emacs.exe" -ArgumentList '-Q', '--batch', '--eval', `(message`(getenv`(symbol-name`'TEEEST`)`)`) -Environment @{TEEEST = 42} -Wait
echo $TEEEST $env:TEEEST

Output:

42
40
41

Note:

  1. It currently only works in pwsh (PowerShell Core) v7.4.

  2. You can't capture stdout/stderr like what you do in Bash (e.g., TEEEST=42 emacs -Q -nw --batch --eval '(print (getenv "TEEEST"))' > a.txt). I tested this by

    Start-Process -NoNewWindow -FilePath "emacs.exe" -ArgumentList '-Q', '--batch', '--eval', `(print`(getenv`(symbol-name`'TEEEST`)`)`) -Environment @{TEEEST = 42} -Wait > a.txt
    

    As @mklement0 mentioned:

    your only options are -RedirectStandardOutput/-RedirectStandardError to send output to files, with no direct ability to merge the streams.

  3. The $LASTEXITCODE is not set. I tested this by

    echo $LASTEXITCODE
    Start-Process -NoNewWindow -FilePath "gcc.exe" -Environment @{TEEEST = 42} -Wait
    echo $LASTEXITCODE  # You may expect it to be 1 because gcc didn't receive arguments.
    

    output (omit the output of gcc)

    0
    0
    
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for updating. Note that it will work in v7.4 and all future pwsh versions, but it won't be back-ported to powershell (Windows PowerShell). The way to get the exit code is by adding -PassThru to the Start-Process call, which makes it output a process-info object whose .ExitCode property you can query. However, there's a bug that currently prevents this with -NoNewWindow - see GitHub issue #20400, which also mentions workarounds.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.