代码之家  ›  专栏  ›  技术社区  ›  Colin Mackay

powershell将换行符放在输出中不适当的位置

  •  4
  • Colin Mackay  · 技术社区  · 8 年前

    我有一个PowerShell脚本,但在继续下一行之前,一些输出在任意点被截断。这真是令人讨厌。

    例如,我可以使用 Write-Host 只要我需要,该行将继续运行(请注意,即在团队城市中运行,团队城市添加了一些前缀信息-但是,通过将输出传输到文件可以观察到相同的效果):

    [10:04:45] [Step 5/7]  - Found Windows Service at G:\TeamCityData\TeamCityBuildAgent-1\work\282b8abc9094651e\Artefacts\windows-services\WindowsService.Dummy\WindowsService.DummyService.exe
    

    其他时候,输出似乎会在任意点被人为截断,就像在窗口中包装一样(窗口不存在)。

    所以,这一行:

    Copy-Item -Path $fullSourcePath -Destination $destPath -Recurse -Verbose -ErrorAction Stop
    

    在团队城市中生成此输出(添加了一些前缀信息):

    [10:04:46] [Step 5/7] VERBOSE: Performing the operation "Copy File" on target "Item: 
    [10:04:46] [Step 5/7] G:\TeamCityData\TeamCityBuildAgent-1\work\282b8abc9094651e\Artefacts\windows-services\WindowsService.Dummy\WindowsServi
    [10:04:46] [Step 5/7] ce.DummyService.exe Destination: 
    [10:04:46] [Step 5/7] \\SERVER001\scheduled-tasks\ProductFolder\Dev\DummyWindowsService\WindowsService.DummyService.exe".
    [10:04:46] [Step 5/7] VERBOSE: Performing the operation "Copy File" on target "Item: 
    [10:04:46] [Step 5/7] G:\TeamCityData\TeamCityBuildAgent-1\work\282b8abc9094651e\Artefacts\windows-services\WindowsService.Dummy\WindowsServi
    [10:04:46] [Step 5/7] ce.DummyService.exe.config Destination: 
    [10:04:46] [Step 5/7] \\SERVER001\scheduled-tasks\ProductFolder\Dev\DummyWindowsService\WindowsService.DummyService.exe.config".
    

    我该如何阻止这种荒谬?我希望输出在行尾正确地呈现换行符,而不是在文件名的中间。

    更新

    下面的评论表明,这是TeamCity获取输出的方式存在问题。但是,如果我直接在PowerShell控制台中执行类似的命令并将输出传输到文件,则会发生相同的问题。

    命令:

    copy-item -Path F:\logs -Destination .\ -Recurse -Verbose *> F:\logs\copy-item-output-1.txt
    

    产生如下输出:

    Performing the operation "Copy File" on target "Item: F:\logs\20161103-140649-ProductName.Program.log 
    Destination: F:\Destination\1234567890abcdefghijklmnopqrstuvwxyz\this-is-a-long-path-name-to-show-wrapping-issues-with-copy-it
    em\logs\20161103-140649-ProductName.Program.log".
    

    如您所见,它还跨行分割文件路径,即使它发送到文件,而不是控制台窗口。

    2 回复  |  直到 7 年前
        1
  •  2
  •   mklement0    8 年前

    以下解决方案: (more than 10 years old so there might exist a smarter way recently?) 两者都适用 PowerShell PowerShell ISE :

    $pshost = get-host
    $pswindow = $pshost.ui.rawui
    $newsize = $pswindow.buffersize
    ### do not change $newsize.height
    $newsize.width = 3000               ### [int] type; max. value unknown at present
    $pswindow.buffersize = $newsize
    
        2
  •  1
  •   user4003407    8 年前

    您可以将其他流重定向到输出流,以便为详细和其他类型的输出提供自定义处理:

    & {
        #Script code here
        Copy-Item -Path $fullSourcePath -Destination $destPath -Recurse -Verbose -ErrorAction Stop
    } *>&1 | % {
        function IsStreamType {
            param($Object, $Type)
            $Property = $_.PSObject.Properties[$Type]
            $null -ne $Property -and $Property.Value -is [bool] -and $Property.Value
        }
    } {
        switch(,$_) {
            {
                $_ -is [System.Management.Automation.DebugRecord] -and
                (IsStreamType $_ WriteDebugStream)
            } {
                "Debug message: $($_.Message)"
            }
            {
                $_ -is [System.Management.Automation.VerboseRecord] -and
                (IsStreamType $_ WriteVerboseStream)
            } {
                "Verbose message: $($_.Message)"
            }
            {
                $_ -is [System.Management.Automation.WarningRecord] -and
                (IsStreamType $_ WriteWarningStream)
            } {
                "Warning message: $($_.Message)"
            }
            default { ,$_ }
        }
    }
    

    我用 ,$_ 而不是普通的 $_ 作为预防措施,以防止在以下情况下出现PowerShell展开行为: $_ 碰巧是集合对象。