Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash/batch-like subshell in Powershell

Tags:

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?

like image 934
Kenn Humborg Avatar asked May 31 '17 10:05

Kenn Humborg


1 Answers

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.

like image 122
Vaelus Avatar answered Nov 16 '22 03:11

Vaelus