Kenn Humborg
Kenn Humborg

Reputation: 343

Bash/batch-like subshell in Powershell

In Unix shell, you can write this:

( cmd1 ; cmd2 ) | cmd3

In Windows Batch, you can write this

( cmd1 & cmd2 ) | cmd3

In both cases, the output of cmd1 and cmd2 is passed to cmd3 on stdin.

Is it possible to do the same in Powershell?

I haven't found a valid syntax that allows this. I'd expect a statement block to work, like this, but it doesn't:

{ cmd1 ; cmd2 } | cmd3

I can get it to work by declaring a function:

function f() {
    cmd1
    cmd2
}
f | cmd3

Is there a syntax that allows this to be done in-line?

Upvotes: 24

Views: 11634

Answers (1)

Vaelus
Vaelus

Reputation: 1065

You can invoke powershell directly to spawn a true subshell (i.e. outer shell's state is not modified by the subshell):

pwsh -Command { cmd1 ; cmd2 } | cmd3

Since powershell takes objects instead of just strings as input, the -Command argument can take a script block. Be aware thst there is some strange behavior if you try to write to non-success, nom-error streams, such as with Write-Host. If you run into these issues, I found it's easiest to just emulate a subshell with a function that saves all relevant state, executes its argument with Invoke-Command or &, then restores the state.

Upvotes: 11

Related Questions