powershell “运行而不调试”或“开始调试”给出与手动运行脚本不同的结果

dba5bblo  于 2023-01-02  发布在  Shell
关注(0)|答案(1)|浏览(127)

下面的测试示例可用于根据运行方式重现不同的结果。

    • 先决条件:**带PowerShell扩展的VSCode。
    • 步骤:**

1.在桌面上创建一个新的*.ps1文件,并将下面的代码粘贴到其中。
1.使用VSCode打开文件,调出终端并运行ex..\filename.ps1

$private:PSDefaultParameterValues = @{}
$private:PSDefaultParameterValues.Add("*:ErrorVariable", "+ErrorBuffer")

function Test-Variable
{
    [CmdletBinding()]
    param ()

    "Test-Variable private: '$($private:PSDefaultParameterValues | Out-String)'"
    "Test-Variable local: '$($local:PSDefaultParameterValues | Out-String)'"
    "Test-Variable script: '$($script:PSDefaultParameterValues | Out-String)'"
    "Test-Variable global: '$($global:PSDefaultParameterValues | Out-String)'"

    $ErrorBuffer = $PSCmdlet.GetVariableValue("ErrorBuffer")
    "Count of errors is $($ErrorBuffer.Count)"

    Write-Error -Message "sample error"

    "Count of errors is $($ErrorBuffer.Count)"
    $ErrorBuffer.Clear()
}

Test-Variable

输出如下:

> .\filename.ps1
Test-Variable private: ''
Test-Variable local: ''
Test-Variable script: ''
Test-Variable global: ''
Count of errors is 0
Write-Error: C:\Users\User\Desktop\filename.ps1:24:1
Line |
  24 |  Test-Variable
     |  ~~~~~~~~~~~~~
     | sample error
Count of errors is 1

接下来,不是在VSCode中手动运行,而是从菜单Run -> Run Without Debugging中选择
下面是新的输出:

C:\Users\User> . 'c:\Users\User\Desktop\filename.ps1'
Test-Variable private: ''
Test-Variable local: ''
Test-Variable script: '
Name                           Value
----                           -----
*:ErrorVariable                +ErrorBuffer

'
Test-Variable global: '
Name                           Value
----                           -----
*:ErrorVariable                +ErrorBuffer

'
Count of errors is 0
Test-Variable: C:\Users\User\Desktop\filename.ps1:24:1
Line |
  24 |  Test-Variable
     |  ~~~~~~~~~~~~~
     | sample error
Count of errors is 2

突然出现了两个错误!我知道这是由于PSDefaultParameterValues没有被考虑,全局和脚本作用域变量被设置,即使我显式地声明它为私有。
您也可以尝试Run -> Start Debugging,结果相同。
我揪了几个小时的头发,试图找出我的代码有什么问题,只是为了发现这个。
问题是,问题是什么,如何解决?
是我的代码错误还是PS extensionVSCode有问题?
我的目标是让这段代码无论我如何运行都产生1个错误计数。
如果你想知道我为什么使用这个方法,这就是我如何在PS中实现自动登录,而不必在任何地方指定-ErrorVariablePSDefaultParameterValues是私有的原因是因为这确保了只有被调用的脚本才能看到它,模块作用域函数和嵌套函数将从调用者那里获得它(CmdletBinding必须存在才能工作)。
我看不出有什么别的办法,这只是这个问题的最小可复制样本。

zkure5ic

zkure5ic1#

问题是通过PowerShell扩展运行脚本-无论是否进行调试:

  • 使用.、点源运算符和...运行脚本
  • ...假定调用作用域是 * global * 作用域,则脚本的代码直接在全局作用域中有效运行。

因此,从函数的Angular 来看(脚本内部运行在一个 * child * 作用域中),$script:$global:作用域是相同的。

    • 解决方法**:

在目标脚本旁边创建一个 * helper * 脚本,比如debugHelper.ps1,其内容如下:

# Call filename.ps1 in a *child* scope.
& $PSScriptRoot/filename.ps1

然后使用 * it * 作为运行或调试代码的入口点。

相关问题