代码之家  ›  专栏  ›  技术社区  ›  Scott Weinstein

使用PowerShell的Measure命令时如何准确报告错误

  •  1
  • Scott Weinstein  · 技术社区  · 15 年前

    当我测试的脚本块中有错误时 Measure-Command ,错误显示在调用行,而不是在引发错误的位置。

    下面是一个例子:

    function ThrowAnError
    {
        Write-Host "in ThrowAnError"
        throw "ThrowAnError"
    }
    
    Measure-Command  { ThrowAnError }
    

    这是在scriptBlockErrors.ps1:6 char:16报告的,我想知道错误发生在 第4行 .

    有什么想法吗?

    2 回复  |  直到 15 年前
        1
  •  3
  •   Keith Hill    15 年前

    正如约翰内斯指出的那样,这个场景在第2版中运行良好。在v1中,您可以在直接运行sriptblock时获得准确的错误行信息,但是measure命令正在执行某些操作,从而导致原始错误的行号丢失。

    在v1中,您可以使用使用.NET秒表类的自定义度量例程来解决这个问题。这个例程非常简单,它在脚本中反映了measure命令在二进制代码中的作用:

    function ThrowAnError
    {    
        Write-Host "in ThrowAnError"    
        throw "ThrowAnError"
    }
    
    function Measure-CommandEx([scriptblock]$expression)
    {
        trap { $sw.Stop(); $sw.Elapsed; break }
        $sw = [Diagnostics.StopWatch]::StartNew()
        &$expression | Out-Null
        $sw.Stop()
        $sw.Elapsed
    }
    
    Measure-CommandEx { ThrowAnError }
    
    Days              : 0
    Hours             : 0
    Minutes           : 0
    Seconds           : 0
    Milliseconds      : 4
    Ticks             : 44832
    TotalDays         : 5.18888888888889E-08
    TotalHours        : 1.24533333333333E-06
    TotalMinutes      : 7.472E-05
    TotalSeconds      : 0.0044832
    TotalMilliseconds : 4.4832
    
    ThrowAnError
    At C:\Documents and Settings\Keith\foo.ps1:4 char:7
    +     throw  <<<< "ThrowAnError"
    

    请注意,对于非常精细的度量,它看起来不像内置的measure命令那么精确,因为在start()和stop()调用的解释和执行过程中会浪费一些时间。但是,对于需要100毫秒(粗略猜测)或更多时间的操作,这应该足够精确。

        2
  •  0
  •   Joey Gumbo    15 年前

    它在PowerShell v2中工作正常:

    PS Home:\> .\x.ps1
    in ThrowAnError
    ThrowAnError
    At C:\...\x.ps1:4 char:10
    +     throw <<<<  "ThrowAnError"
        + CategoryInfo          : OperationStopped: (ThrowAnError:String) [], RuntimeException
        + FullyQualifiedErrorId : ThrowAnError
    

    但对于PowerShell v1,我担心你运气不好。