Powershell 动力壳压痕
我正在编写一个部署应用程序的大型脚本。此脚本基于几个嵌套函数调用 有没有办法根据深度“识别”输出 例如,我有:Powershell 动力壳压痕,powershell,Powershell,我正在编写一个部署应用程序的大型脚本。此脚本基于几个嵌套函数调用 有没有办法根据深度“识别”输出 例如,我有: function myFn() { Write-Host "Start of myfn" myFnNested() Write-Host "End of myfn" } function myFnNested() { Write-Host "Start of myFnNested" Write-Host "End of myFnNested" }
function myFn()
{
Write-Host "Start of myfn"
myFnNested()
Write-Host "End of myfn"
}
function myFnNested()
{
Write-Host "Start of myFnNested"
Write-Host "End of myFnNested"
}
Write-Host "Start of myscript"
Write-Host "End of myscript"
脚本的输出将是:
我想要实现的是这个输出:
因为我不想几乎不编码空格的数量(因为我不知道复杂脚本中的深度级别)。我怎样才能简单地达到我的目标
也许是这样的
function myFn()
{
Indent()
Write-Host "Start of myfn"
myFnNested()
Write-Host "End of myfn"
UnIndent()
}
function myFnNested()
{
Indent()
Write-Host "Start of myFnNested"
Write-Host "End of myFnNested"
UnIndent()
}
Write-Host "Start of myscript"
Write-Host "End of myscript"
您可以在
write host
周围使用包装函数,该函数使用$MyInvocation
确定堆栈深度,以创建大量空格作为消息前缀
将其与Get Variable
的-scopeèn›
参数相结合,以拉出每个调用级别…类似于从Windows PowerShell中改编的showstack
函数(Payette,第1版):
在由于作用域计数过高而导致
获取变量
失败之前,您需要管道中的最大值$\ucode>。您可以使用Console.CursorLeft设置其位置。请注意,写入输出将重置任何自定义位置,因此您需要在每次输出后重置它。以下是一个示例:
$i = 0
function Indent() {
[console]::CursorLeft += 2
$i = [console]::CursorLeft
$i
}
function UnIndent() {
if($i -gt 0) { $i -= 2 }
[console]::CursorLeft = $i
$i
}
function WriteIndent([string]$s) {
[console]::CursorLeft += $i
write-host $s
# Reset indent, as write-host will set cursor to indent 0
[console]::CursorLeft += $i
}
function myFnNested() {
$i = Indent
WriteIndent "Start of myFnNested"
WriteIndent "End of myFnNested"
$i = UnIndent
}
function myFn() {
$i = Indent
WriteIndent "Start of myfn"
myFnNested
WriteIndent "End of myfn"
$i = UnIndent
}
WriteIndent "Start of myscript"
myFn
WriteIndent "End of myscript"
$i=0
函数缩进(){
[控制台]::CursorLeft+=2
$i=[控制台]::光标左键
$i
}
函数UnIndent(){
如果($i-gt 0){$i-=2}
[控制台]::CursorLeft=$i
$i
}
函数WriteIndent([string]$s){
[控制台]::CursorLeft+=$i
写入主机$s
#重置缩进,因为写入主机将光标设置为缩进0
[控制台]::CursorLeft+=$i
}
函数myFnNested(){
$i=缩进
WriteIndent“myFnNested的开始”
WriteIndent“myFnNested的结尾”
$i=未登录
}
函数myFn(){
$i=缩进
WriteIndent“myfn的开始”
myFnNested
WriteIndent“myfn的结束”
$i=未登录
}
WriteIndent“myscript的开始”
myFn
WriteIndent“myscript的结尾”
输出:
PS C:\scripting> .\Indent-Output.ps1
Start of myscript
Start of myfn
Start of myFnNested
End of myFnNested
End of myfn
End of myscript
PS C:\scripting>\Indent-Output.ps1
myscript的开始
多年筹资框架的开始
myfn的开始
myfn结束
myfn的结束
myscript的结尾
编写一个调试函数。两个参数,一个是标志,用于开始、停止或注释;另一个参数应该是调试文本。(我将使用1、-1和0作为标志,然后您可以将标志添加到缩进变量以设置增量深度。虽然很愚蠢,但足以进行调试。)查看此脚本
如果加载该写详细包装器,可以设置$WriteHostAutoIndent=$true
,然后调用Write Host,它将根据堆栈深度缩进。根据您最初定义的这些函数:
function myFn()
{
Write-Host "Start of myfn"
myFnNested
Write-Host "End of myfn"
}
function myFnNested()
{
Write-Host "Start of myFnNested"
Write-Host "End of myFnNested"
}
在不做任何更改的情况下,您只需点源一个脚本文件,其中包含Write Host wrapper函数:
C:\PS> . C:\Users\Jaykul\Documents\WindowsPowerShell\PoshCode\3386.ps1
然后在调用函数之前只需设置首选项变量:
C:\PS> $WriteHostAutoIndent = $true
C:\PS> myFn
Start of myfn
Start of myFnNested
End of myFnNested
End of myfn
漂亮的缩进输出,就像魔术一样;-) 我用了另一种思路。我设置了一个计数变量,该变量在函数开始时递增,然后使用以下代码填充我正在写入的行:
write-host ($string).PadLeft( ($string).length + (2 * $count) )
这将为每个递归缩进两个空格。在使用“&”运算符和名称空间调用原始字符串之前,您可以重写Write Host
以写入缩进。您可能能够从当前堆栈范围派生缩进量,但是全局变量提供了更多的控制
$global:writeHostIndent
function Write-Host
{
Microsoft.PowerShell.Utility\Write-Host (' ' * $global:writeHostIndent) -NoNewline
& 'Microsoft.PowerShell.Utility\Write-Host' $args
}
隐马尔可夫模型。。。虽然这里的解决方案对某些人来说是显而易见的,但对每个人来说可能都不那么显而易见。。。好吧,也许只是我有精神障碍。如何调整写入主机包装函数中的想法?@msorens这里的基本想法是循环堆栈,依靠Get Variable
在到达堆栈顶部时抛出。在这种情况下,需要过滤表示堆栈帧的$MyInvocation
值,在堆栈帧中需要额外的缩进级别(例如,调用MyRecursiveFunction
)。您如何找到时间编写如此出色的脚本?:)github上有一个指向此脚本的链接,以防其他人正在查找它:&'Microsoft..\WriteHost'$args
似乎无法正确解析args,我在命令行上传递的任何其他选项都是消息的一部分。糟糕的方法是,每次写主机调用都必须重复此操作。保持干燥
C:\PS> $WriteHostAutoIndent = $true
C:\PS> myFn
Start of myfn
Start of myFnNested
End of myFnNested
End of myfn
write-host ($string).PadLeft( ($string).length + (2 * $count) )
$global:writeHostIndent
function Write-Host
{
Microsoft.PowerShell.Utility\Write-Host (' ' * $global:writeHostIndent) -NoNewline
& 'Microsoft.PowerShell.Utility\Write-Host' $args
}