PowerShell字符串插值场景下获取调用栈(Stack Trace)的异常问题:参数内插值导致无法定位实际调用位置
PowerShell字符串插值场景下获取调用栈(Stack Trace)的异常问题:参数内插值导致无法定位实际调用位置
我最近在做PowerShell模板生成的需求时碰到了一个棘手的问题:我写了一批用来生成代码字符串的函数,希望它们能自动检测当前的缩进深度,不用每次调用都手动传入缩进参数。最开始我想着用Get-PSCallStack来实现自动定位,但实际测试时发现了一个不符合预期的情况。
先看能正常工作的场景:我写了一个Get-PosInString函数,用来获取它在字符串插值中的起始位置,代码如下:
function Get-PosInString { param($SomeParam) # 调试输出调用栈信息 (Get-PSCallStack)[1] | Format-List | Out-String (Get-PSCallStack)[1].Position | Format-List | Out-String # 计算并返回偏移量,减去`$(`的长度(2个字符) Write-Output (((Get-PSCallStack)[1]).Position.StartOffset - 2) }
当我直接执行"hello $(Get-PosInString)"时,结果完全符合预期:函数返回了正确的偏移量7,调试输出的栈信息也能明确看到调用位置是<ScriptBlock>中的Get-PosInString。
但一旦我给函数的参数也加入字符串插值,比如执行"hello $(Get-PosInString "$('argvalue')")",问题就出现了!这时候Get-PSCallStack[1]指向的居然是参数里的'argvalue'表达式,返回的偏移量变成了38,完全偏离了我想要定位的函数调用位置。
我个人觉得这应该是PowerShell的一个bug:按照逻辑,参数内的插值操作应该在函数调用前就完成计算,当进入函数内部执行时,调用栈应该指向实际发起函数调用的位置,而不是参数里的插值代码。
我已经针对这个问题提交了官方反馈,希望后续能得到修复。
备注:内容来源于stack exchange,提问作者Brett
相关产品推荐
相关产品推荐

