我正在编写一个部署应用程序的大型脚本。此脚本基于多个嵌套函数调用。
有没有办法去识别" ident"输出基于深度?
例如,我有:
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"
脚本的输出将是:
Start of myscript Start of myfn Start of myfnNested End of myFnNested End of myFn End of myscript
我想要实现的是这个输出:
Start of myscript Start of myfn Start of myfnNested End of myFnNested End of myFn 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"
答案 0 :(得分:6)
您可以在write-host
周围使用包装函数,该函数使用$MyInvocation
来确定堆栈深度,以创建多个空格来为邮件添加前缀。
将此与-scope ‹n›
的{{1}}参数相结合,以提取每个调用级别...类似于从{em> Windows PowerShell In Action (Payette)改编的Get-Variable
函数,1 st Ed):
showstack
在function ShowStack {
trap { continue; }
0..100 | Foreach-Object {
(Get-Variable -scope $_ 'MyInvocation').Value.PositionMessage -replace "`n"
}
}
因范围计数过高而失败之前,您需要管道中的$_
的最大值。
答案 1 :(得分:4)
查看此脚本http://poshcode.org/scripts/3386.html
如果你加载了Write-Verbose包装器,你可以设置$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包装函数来点源脚本文件:
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
漂亮的缩进输出,就像魔法一样; - )
答案 2 :(得分:1)
我用了另一种思路。我设置了一个计数变量,该变量在函数开始时递增,然后使用以下代码填充我正在编写的行:
write-host ($string).PadLeft( ($string).length + (2 * $count) )
这将为每次递归缩进两个空格。
答案 3 :(得分:0)
您可以使用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"
输出:
PS C:\scripting> .\Indent-Output.ps1 Start of myscript Start of myfn Start of myFnNested End of myFnNested End of myfn End of myscript
答案 4 :(得分:0)
编写DEBUG函数。两个参数,一个是带开始,停止或注释的标志;另一个参数应该是调试文本。 (我使用1,-1和0作为标志,然后你可以将标志添加到Indent变量来设置增量深度。愚蠢但足以进行调试。)
答案 5 :(得分:0)
您可以在使用'&'调用原始内容之前覆盖Write-Host
来编写缩进运算符和命名空间。您可以从当前堆栈范围派生缩进量,但全局变量可以为您提供更多控制。
$global:writeHostIndent
function Write-Host
{
Microsoft.PowerShell.Utility\Write-Host (' ' * $global:writeHostIndent) -NoNewline
& 'Microsoft.PowerShell.Utility\Write-Host' $args
}