There are four ways to suppress an output:
$null variable
PS C:\> 1; $(2; return) > $null; 3
1
3
Out-Null cmdlet
PS C:\> 1; $(2; return) | Out-Null; 3
1
2
[void] type
PS C:\> 1; [void]$(2; return); 3
1
2
$null variable
PS C:\> 1; $null = $(2; return); 3
1
2
All four cases are expected to be equivalent.
Why redirection to $null behaves different? Have I faced a bug?
This example shows unexpected behavior of > $null command in PS 2.0:
PS C:\> 1; $(Write-Output 2; Write-Host 3; return; Write-Host 4) > $null; 5
1
3
5
return command acts as if it exits from some nested context (though there is no command which creates it), stops $() expression execution and then continues the execution (when it shouldn't) in the current context to the Write-Output 5 command.
(from wOxxOm's answer)
> $null operation is executed before $() expression and suppresses its output; return command does not exit from the current context (considered a BUG), but stops $() expression execution> $null operation is executed before $() expression and suppresses its output in all cases; return command exits from the current context completely| Out-Null, [void], $null = operations are executed after $() expression and suppress its output if there is no return command in it; return command exits from the current context completelyDifferent methods for suppressing command output:
... > $null redirection to $null variable... | Out-Null piping to Out-Null cmdlet[void]... casting to [void] type$null = ... assignment to $null variable2 is actually executed as Write-Output 2
$() executes the enclosed code in the same context, it doesn't create a new context.
Things that create a new context are scriptblocks like & { ... }, 1..2 | ForEach { ... },({ ... }).Invoke(), select @{N='calculated property'; E={$_.foo}} and functions.
Thus, $( return ) exits from the current context so nothing should be evaluated after that (in other words PowerShell 1.0 and 2.0 have a bug).
1; $(2; return) > $null; 3
The output stream itself of the entire $() expression is suppressed with >$null, which is decided before the expression is evaluated, return exits from the current context before 3 gets a chance.
PS 3 (and newer) correctly prints only 1:
1
PS 1 and 2 incorrectly print both numbers and indeed it's a bug:
1
3
1; [void]$(2; return); 3
1; $null = $(2; return); 3
1; $(2; return) | Out-Null; 3
1
2
2 is pushed to the output stream here, then return exits the current context before subsequent operation can take place (casting, assigning, pipelining).
As for performance differences, see this answer: | Out-Null is the slowest because it creates a pipeline which is a complex process; the other methods discard the output, no extras created.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With