[英]PowerShell switch parameter doesn't work as expected
I have the following PowerShell function to help me do benchmarks.我有以下 PowerShell function 来帮助我做基准测试。 The idea is that you provide the command and a number and the function will run the code that number of times.
这个想法是您提供命令和一个数字,function 将运行该代码的次数。 After that the function will report the testing result, such as Min, Max and Average time taken.
之后 function 将报告测试结果,例如所用的最小、最大和平均时间。
function Measure-MyCommand()
{
[CmdletBinding()]
Param (
[Parameter(Mandatory = $True)] [scriptblock] $ScriptBlock,
[Parameter()] [int] $Count = 1,
[Parameter()] [switch] $ShowOutput
)
$time_elapsed = @();
while($Count -ge 1) {
$timer = New-Object 'Diagnostics.Stopwatch';
$timer.Start();
$temp = & $ScriptBlock;
if($ShowOutput) {
Write-Output $temp;
}
$timer.Stop();
$time_elapsed += $timer.Elapsed;
$Count--;
}
$stats = $time_elapsed | Measure-Object -Average -Minimum -Maximum -Property Ticks;
Write-Host "Min: $((New-Object 'System.TimeSpan' $stats.Minimum).TotalMilliseconds) ms";
Write-Host "Max: $((New-Object 'System.TimeSpan' $stats.Maximum).TotalMilliseconds) ms";
Write-Host "Avg: $((New-Object 'System.TimeSpan' $stats.Average).TotalMilliseconds) ms";
}
The problem is with the switch
parameter $ShowOutput
.问题出在
switch
参数$ShowOutput
。 As I understand, when you provide a switch parameter, its value is true.据我了解,当您提供开关参数时,它的值为真。 Otherwise it's false.
否则就是假的。 However it doesn't seem to work.
但是它似乎不起作用。 See my testing.
看我的测试。
PS C:\> Measure-MyCommand -ScriptBlock {Write-Host "f"} -Count 3 -ShowOutput
f
f
f
Min: 0.4935 ms
Max: 0.8392 ms
Avg: 0.6115 ms
PS C:\> Measure-MyCommand -ScriptBlock {Write-Host "f"} -Count 3
f
f
f
Min: 0.4955 ms
Max: 0.8296 ms
Avg: 0.6251 ms
PS C:\>
Can anyone help to explain it please?谁能帮忙解释一下?
This is because Write-Host
doesn't return the object and is not a part of pipeline stream, instead it sends text directly to console.这是因为
Write-Host
不返回 object 并且不是管道 stream 的一部分,而是直接将文本发送到控制台。 You can't simply hide Write-Host
output by writing it to variable, because Write-Host
writes to console stream which isn't exposed in PowerShell before version 5. What you need is to replace Write-Host
with Write-Output
cmdlet call.您不能简单地通过将
Write-Host
output 写入变量来隐藏它,因为Write-Host
写入控制台 stream,在版本 5 之前的 PowerShell 中未公开。您需要的是用Write-Output
cmdlet 调用替换Write-Host
. Then you get what you expect.然后你得到你所期望的。 This solution is valid for PowerShell 2.0+.
此解决方案适用于 PowerShell 2.0+。
Update:更新:
Starting with PowerShell 5, Write-Host
writes to its dedicated stream and you can handle and redirect this stream somewhere else.从 PowerShell 5 开始,
Write-Host
写入其专用的 stream,您可以处理并将此 stream 重定向到其他地方。 See this response for more details: https://stackoverflow.com/a/60353648/3997611 .有关详细信息,请参阅此回复: https://stackoverflow.com/a/60353648/3997611 。
The problem is with the specific script block you're passing, not with your [switch]
parameter declaration (which works fine):问题在于您传递的特定脚本块,而不是您的
[switch]
参数声明(工作正常):
{Write-Host "f"}
By using Write-Host
, you're bypassing PowerShell's success output stream (which the assignment to variable $temp
collects) and printing directly to the host [1] (the console), so your output always prints.通过使用
Write-Host
,您将绕过PowerShell 的成功 output stream(分配给变量$temp
收集)并直接打印到主机[1] (控制台),因此您的 output始终打印。
To print to the success output stream, use Write-Output
, or better yet, use PowerShell's implicit output feature:要打印成功 output stream,请使用
Write-Output
,或者更好的是,使用 PowerShell 的隐式output 功能:
# "f", due not being capture or redirected, is implicitly sent
# to the success output stream.
Measure-MyCommand -ScriptBlock { "f" } -Count 3 -ShowOutput
[1] In PowerShell 5.0 and higher, Write-Host
now writes to a new stream, the information stream (number 6
), which by default prints to the host. [1] 在 PowerShell 5.0 及更高版本中,
Write-Host
现在写入一个新的 stream,信息 stream(数字6
),默认打印到主机。 See about_Redirection
.请参阅
about_Redirection
。 Therefore, a 6>
redirection now does allow you to capture Write-Host
output;因此,
6>
重定向现在允许您捕获Write-Host
output ; eg: $temp = Write-Host hi 6>&1
.例如:
$temp = Write-Host hi 6>&1
。 Note that the type of the objects captured this way is System.Management.Automation.InformationRecord
.请注意,以这种方式捕获的对象的类型是
System.Management.Automation.InformationRecord
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.