powershell indentation

后端 未结 6 1639
小蘑菇
小蘑菇 2021-02-14 12:05

I\'m writing a large script that deploys an application. This script is based on several nested function calls.

Is there any way to \"ident\" the output based on the dep

相关标签:
6条回答
  • 2021-02-14 12:40

    You can override Write-Host to write your indents before calling the original with the '&' operator and the namespace. You might be able to derive the amount of indentation from the current stack scope, but a global variable gives you more control.

    $global:writeHostIndent
    
    function Write-Host
    {
        Microsoft.PowerShell.Utility\Write-Host (' ' * $global:writeHostIndent) -NoNewline
        & 'Microsoft.PowerShell.Utility\Write-Host' $args
    }
    
    0 讨论(0)
  • 2021-02-14 12:52

    You can use Console.CursorLeft to set its position. Be aware that write-output will reset any custom location, so you need to reset it after each output. Here is a sample:

        $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"
    

    Output:

        PS C:\scripting> .\Indent-Output.ps1
        Start of myscript
            Start of myfn
                Start of myFnNested
                End of myFnNested
            End of myfn 
        End of myscript
    
    0 讨论(0)
  • 2021-02-14 12:55

    Write a DEBUG function. Two arguments, one is a flag that takes Start, Stop, or Note; the other argument should be the debug text. (I'd use 1, -1, and 0 for the flag, then you can just add the flag to a Indent variable to set increment depth. Stupid but good enough for debugging.)

    0 讨论(0)
  • 2021-02-14 12:56

    You could use a wrapper function around write-host which used $MyInvocation to determine the stack depth to create a number of spaces to prefix the message.

    Combine this with the -scope ‹n› parameter of Get-Variable to pull out each calling level… something like the showstack function adapted from Windows PowerShell In Action (Payette, 1st Ed):

    function ShowStack {
      trap { continue; }
      0..100 | Foreach-Object {
        (Get-Variable -scope $_ 'MyInvocation').Value.PositionMessage -replace "`n"
      }
    }
    

    You'll need the maximum value of $_ in the pipeline before Get-Variable fails for scope count being too high.

    0 讨论(0)
  • 2021-02-14 12:57

    Check out this script http://poshcode.org/scripts/3386.html

    If you load up that Write-Verbose wrapper, you can set $WriteHostAutoIndent = $true and then just call Write-Host and it will be indented based on stack depth. So given these functions as you defined them originally:

    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"
    }
    

    With no changes, you can just dot-source a script file with that Write-Host wrapper function in it:

    C:\PS> . C:\Users\Jaykul\Documents\WindowsPowerShell\PoshCode\3386.ps1
    

    And then merely set the preference variable before you call your function:

    C:\PS> $WriteHostAutoIndent = $true
    C:\PS> myFn
      Start of myfn
        Start of myFnNested
        End of myFnNested
      End of myfn
    

    Beautiful indented output, like magic ;-)

    0 讨论(0)
  • 2021-02-14 12:58

    I used another line of thinking. I set a count variable that is incremented at the start of the function and then used the following code to pad the line I was writing:

    write-host ($string).PadLeft( ($string).length + (2 * $count) )
    

    This will indent two spaces for every recursion.

    0 讨论(0)
提交回复
热议问题