Лучший способ напечатать объект, чем Write-Host - PullRequest
6 голосов
/ 24 апреля 2009

Я использую Write-Host для анализа объектов, но иногда трудно понять, что это за объект на самом деле.

Рассмотрим:

Write-Host $null
Write-Host @()
Write-Host @($null, $null)

Отпечатки:

# Actually it prints nothing

Я бы хотел что-то вроде этого:

Null
@()
@(Null, Null)

Есть предложения?

Ответы [ 5 ]

5 голосов
/ 02 февраля 2011

В этом конкретном примере вы можете легко получить то, что хотите, вставив их в свойство объекта. Для примера, давайте создадим массив с тремя тестами:

$tests = @($null,@(), @($null,$null))

function Write-Visible {
   param($InputObject) 

   New-Object PSObject -Property @{ Object=$InputObject } | 
       Out-String | Out-Host 
}

Конечно, Out-String | Out-Host - это просто чтобы убедиться, что мы на самом деле не выводим объекты в конвейер, а ведем себя как Write-Host.

Итак, теперь мы можем запустить наши тесты:

PS> Write-Visible $tests[0]

Object
------


PS> Write-Visible $tests[1]

Object
------
{}


PS> Write-Visible $tests[2]

Object
------
{$null, $null}

Конечно, проблема в том, что он не очень хорошо работает с реальными объектами, потому что он превращает их в свойства объекта, где они визуализируются как "ToString ()" ... однако, вне вершины моя голова, я не могу думать, как вызвать магию рендеринга, которая происходит там без нового объекта.

2 голосов
/ 24 апреля 2009

Вы можете написать функцию, которая сделает красивую печать за вас. Что-то вроде следующего может работать для ваших нужд:

function pp($a) {
    if ($a -eq $null) {
        return "Null"
    } elseif ($a -is [object[]]) {
        $b = @()
        foreach ($x in $a) {
            $b += (pp $x)
        }
        $s = "@(" + [string]::Join(",", $b) + ")"
        return $s
    } else {
        return $a
    }
}

Это, однако, все еще имеет проблемы с пустым массивом на оболочке (хотя работает нормально из файла .ps1). Также Hashtables не поддерживаются, но вложенные массивы. Вероятно, все еще нуждается в некотором слесарном деле, но мог бы дать общее руководство.

Массив @($null, $null) кажется уродливым чудовищем, сопротивляясь даже сравнивая его с $null. Weird.

1 голос
/ 30 марта 2011

Не работает для пустых массивов, но вы можете использовать одну из команд format-xxx. Это помогает для форматирования объектов, которые не имеют полезного переопределения ToString. Например.

> $cmd = Get-Command -Name get-command
> $cmd

CommandType     Name                                                Definition
-----------     ----                                                ----------
Cmdlet          Get-Command                                         Get-Command...

> write-host $cmd
Get-Command
> format-table -InputObject $cmd | out-string | out-host

CommandType     Name                                                Definition
-----------     ----                                                ----------
Cmdlet          Get-Command                                         Get-Command... 
1 голос
/ 01 февраля 2011

Будет несколько проблем, пытающихся сделать что-то подобное.

  1. «Правильный» или «powershell» способ изменить работу write-host - это использовать файлы форматирования, чтобы определить, как вы хотите, чтобы хост, который вы используете, отображал рассматриваемые объекты. Вы можете получить дополнительную информацию из get-help about_format.ps1xml или из страниц форматирования MSDN PowerShell страниц.
  2. Вы должны быть конкретны для "хоста", который вы используете. Для получения дополнительной информации см. get-help get-host или страницу TechNet . Есть В НАИМЕНЬШЕМ трех общих хостах, о которых вы хотите знать:
    • базовая командная строка, ConsoleHost
    • базовый PowerShell ISE, Windows PowerShell ISE Host
    • хост Quest PowerGUI, PowerGUIScriptEditorHost
  3. PowerShell обрабатывает синтаксис @ () особым образом, что иногда затрудняет работу с пустыми массивами. Согласно этой записи блога MSDN PowerShell :

    ... операция

    @( … )

    является синтаксическим сахаром для

    [array] $( … )

    Так что - если операторы в @ () возвращают скаляр, он будет заключен в массив но если результат уже является массивом, он не будет вложенным ...

Я бы хотел предоставить какой-то код для этого, но на данный момент он немного за мной ...

0 голосов
/ 25 января 2013

Вы можете попробовать это:

Write-Host '$null'
Write-Host '@()'
Write-Host '@($null, $null)'
...