在 Powershell 脚本中跟踪输出的来源
Tracing where output is coming from in a Powershell script
是否可以在 Powershell 脚本中跟踪输出(到控制台)的来源?我有一个脚本正在向我输出信息,但我不确定输出的是哪一行。例如,是否可以使用 Set-PSBreakpoint 并告诉它在信息返回到控制台时中断?
干杯
我收到了数百个 "False" 返回的消息。
这是输出来自的代码部分:
$ar = Function-which_returns_array_of_objects
$gr = Function-which_returns_array_of_objects
Write-Host "To begin with..."
Write-Host "$($ar.count) assets"
Write-Host "$($gr.count) goods"
foreach($asset in $ar){
if(!(Test-NoNA -string $asset.Serial)){continue}
#See if the particular serial number exists in Goods Received
$found = @()
$gr | Where {$_.SerialNumber -eq $asset.serial} | %{
$found += $_
# and then mark the entry as one that has to be deleted from GR
$_.Delete = "YES"
}
if($found.count -eq 1){
#Serial Number has been found once in GR
#We want to check its PN...
if(Test-NoNA -string $found.PartNumber -and $found.PartNumber -ne $asset.Model){
#add it to the asset if its good and not the same as the model number...
$asset.PartNumber -eq $found.PartNumber
}
}elseif(!$found -or $found.count -eq 0){
#No entries found in GR
#Shouldn't be the case but doesn't actually do any damage as we'd be deleting the GR entry anyway
}elseif($found.count -gt 1){
#More than one match for the SN - probably means a SN like "N/A" has got through the earlier checks
Write-Warning "More than one match for SN: '$($asset.serial)'"
}else{
#Default catcher
Write-Warning "Unknown Error for SN: '$($asset.serial)'"
}
}
此外,这里是 Test-NoNA:
function Test-NoNA($string){
#check that the given string is not blank, N/A, ?, etc. Returns true if string is good
if($string -and $string -ne "" -and $string -ne "N/A" -and $string -ne "NA" -and $string -ne '?' -and $string -isnot [System.DBNull]){return $true}
}
是的,试试这个。这应该在第一次找到写语句的地方中断。
Set-PSBreakpoint -Script Sample.ps1 -Command "write*"
此命令在 Sample.ps1 脚本中以 write 开头的每个命令设置断点,例如 Write-Host。更多
参考 docs
不幸的是,
Set-PSBreakpoint -Command
与 explicit cmdlet calls,
- 例如,在脚本
./myscript.ps1
中调用 Write-Output
和 Write-Host
会导致通过先前的 Set-PSBreakpoint -Command Write-* ./myscript.ps1
调用进入调试器),
但是是否不使用隐式输出,来自语句其输出既不被捕获也不被重定向(例如,'foo'
、1 + 2
、Get-Date
)。
在手头的特定情况下,由于混淆了 -eq
运算符(比较)与 =
,$asset.PartNumber -eq $found.PartNumber
等语句导致了不需要的输出运算符(赋值),由 Lee_Daily 诊断。 -eq
产生输出(比较的布尔结果),而 =
不产生输出。
解决方法:
运行 Set-PSDebug -Trace 1
在调用脚本之前, 在输出之前打印每个源代码行它产生s,如果有的话。 -Trace 2
提供更多详细信息。
使用以下技术,它 告诉您产生成功输出的每个语句的位置和源代码,无论是隐式还是显式:
./myscript.ps1 | % { Write-Verbose -vb "Output from $(($entry=(Get-PsCallStack)[1]).Location): $($entry.Position.Text)"; $_ }
- 脚本的成功输出通过
ForEach-Object
(%
), producing a verbose message reporting the location (script path and line number) as well as the source code of the originating statement (obtained via Get-PSCallStack
) 一个对象一个对象地处理,然后将手头的对象 ($_
) 通过。
如果您想检查给定行上脚本的运行时状态,请说15
:
Set-PSBreakpoint -Script ./myscript.ps1 -Line 15
或者,在 PSv5+ 中,如果修改脚本(临时)是一个选项,请在您的脚本中您想要进入调试器的位置放置一个 Wait-Debugger
调用.
使用 Visual Studio Code with the PowerShell extension 的调试功能 设置断点 and/or 逐步执行脚本 逐个陈述。
- 或者,直接在 PowerShell window.
中使用 Set-PSDebug -Step
进行等效操作
是否可以在 Powershell 脚本中跟踪输出(到控制台)的来源?我有一个脚本正在向我输出信息,但我不确定输出的是哪一行。例如,是否可以使用 Set-PSBreakpoint 并告诉它在信息返回到控制台时中断?
干杯
我收到了数百个 "False" 返回的消息。 这是输出来自的代码部分:
$ar = Function-which_returns_array_of_objects
$gr = Function-which_returns_array_of_objects
Write-Host "To begin with..."
Write-Host "$($ar.count) assets"
Write-Host "$($gr.count) goods"
foreach($asset in $ar){
if(!(Test-NoNA -string $asset.Serial)){continue}
#See if the particular serial number exists in Goods Received
$found = @()
$gr | Where {$_.SerialNumber -eq $asset.serial} | %{
$found += $_
# and then mark the entry as one that has to be deleted from GR
$_.Delete = "YES"
}
if($found.count -eq 1){
#Serial Number has been found once in GR
#We want to check its PN...
if(Test-NoNA -string $found.PartNumber -and $found.PartNumber -ne $asset.Model){
#add it to the asset if its good and not the same as the model number...
$asset.PartNumber -eq $found.PartNumber
}
}elseif(!$found -or $found.count -eq 0){
#No entries found in GR
#Shouldn't be the case but doesn't actually do any damage as we'd be deleting the GR entry anyway
}elseif($found.count -gt 1){
#More than one match for the SN - probably means a SN like "N/A" has got through the earlier checks
Write-Warning "More than one match for SN: '$($asset.serial)'"
}else{
#Default catcher
Write-Warning "Unknown Error for SN: '$($asset.serial)'"
}
}
此外,这里是 Test-NoNA:
function Test-NoNA($string){
#check that the given string is not blank, N/A, ?, etc. Returns true if string is good
if($string -and $string -ne "" -and $string -ne "N/A" -and $string -ne "NA" -and $string -ne '?' -and $string -isnot [System.DBNull]){return $true}
}
是的,试试这个。这应该在第一次找到写语句的地方中断。
Set-PSBreakpoint -Script Sample.ps1 -Command "write*"
此命令在 Sample.ps1 脚本中以 write 开头的每个命令设置断点,例如 Write-Host。更多 参考 docs
不幸的是,
Set-PSBreakpoint -Command
与 explicit cmdlet calls,- 例如,在脚本
./myscript.ps1
中调用Write-Output
和Write-Host
会导致通过先前的Set-PSBreakpoint -Command Write-* ./myscript.ps1
调用进入调试器),
- 例如,在脚本
但是是否不使用隐式输出,来自语句其输出既不被捕获也不被重定向(例如,
'foo'
、1 + 2
、Get-Date
)。
在手头的特定情况下,由于混淆了 -eq
运算符(比较)与 =
,$asset.PartNumber -eq $found.PartNumber
等语句导致了不需要的输出运算符(赋值),由 Lee_Daily 诊断。 -eq
产生输出(比较的布尔结果),而 =
不产生输出。
解决方法:
运行
Set-PSDebug -Trace 1
在调用脚本之前, 在输出之前打印每个源代码行它产生s,如果有的话。-Trace 2
提供更多详细信息。使用以下技术,它 告诉您产生成功输出的每个语句的位置和源代码,无论是隐式还是显式:
./myscript.ps1 | % { Write-Verbose -vb "Output from $(($entry=(Get-PsCallStack)[1]).Location): $($entry.Position.Text)"; $_ }
- 脚本的成功输出通过
ForEach-Object
(%
), producing a verbose message reporting the location (script path and line number) as well as the source code of the originating statement (obtained viaGet-PSCallStack
) 一个对象一个对象地处理,然后将手头的对象 ($_
) 通过。
- 脚本的成功输出通过
如果您想检查给定行上脚本的运行时状态,请说
15
:Set-PSBreakpoint -Script ./myscript.ps1 -Line 15
或者,在 PSv5+ 中,如果修改脚本(临时)是一个选项,请在您的脚本中您想要进入调试器的位置放置一个
Wait-Debugger
调用.
使用 Visual Studio Code with the PowerShell extension 的调试功能 设置断点 and/or 逐步执行脚本 逐个陈述。
- 或者,直接在 PowerShell window. 中使用
Set-PSDebug -Step
进行等效操作