Powershell: подавить вывод на консоль, если она конвейерная

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

Function test1
{
    param(
    [Parameter(Mandatory=$false,ValueFromPipeline=$True)]
    $PrevRes = 0)
    write-host "alfa"
    return ($PrevRes+1)
}

Function test2
{
 param(
    [Parameter(Mandatory=$false,ValueFromPipeline=$True)]
    $PrevRes = 0)
    write-host "beta"
    return ($PrevRes+1) 
}

Function test3
{
 param(
    [Parameter(Mandatory=$false,ValueFromPipeline=$True)]
    $PrevRes = 0)
    write-host "omega"
    return ($PrevRes+1)
}

test1 gives:  
alfa
1

when test1 | test2:
alfa
beta
2

when test | test2 | test3:
alfa
beta
omega
3

when test | test3 | test2:
alfa
omega
beta
3

Проблема в том, что я не знаю, в каком порядке будут вызываться эти функции, и мне нужно убедиться, что в конце нет конвейера, результат не будет выведен на экран, но мне все еще нужно получить доступ к значению. сам.

Я хочу вывод, как это:

test1 gives:  
alfa


when test1 | test2:
alfa
beta


when test | test2 | test3:
alfa
beta
omega


when test | test3 | test2:
alfa
omega
beta

Это инструмент для клиента, поэтому решение, например:

$tst = test1 |test2

это не хорошо, потому что вы знаете, клиент есть клиент, он не знал бы, как его использовать.

Есть ли способ сделать это с PowerShell, который я пропустил онлайн?

Любое решение будет полезно, если оно не связано с какими-либо действиями со стороны клиента.

заранее спасибо

2 ответа

Решение

Ответить на вопрос

Есть ли способ определить в самой функции, является ли возвращаемое значение конвейерным или нет?

Да, есть. Осмотреть $MyInvocation автоматическая переменная и сравнить PipelineLength а также PipelinePosition свойства:

if($MyInvocation.PipelinePosition -lt $MyInvocation.PipelineLength){
    return $PrevRes + 1
}

Оригинальный ответ следует ниже.


Очень простое решение:

Не использовать Write-Host в ваших сценариях.

Как видно из названия, он будет писать вещи напрямую в хост- приложение

Если вам нужно сохранить эти операторы для целей отладки, используйте Write-Debug или же Write-Verbose вместо командлетов:

function test1
{
    param(
    [Parameter(Mandatory=$false,ValueFromPipeline=$True)]
    $PrevRes = 0)
    Write-Verbose "alfa"
    return ($PrevRes+1)
}

function test2
{
 param(
    [Parameter(Mandatory=$false,ValueFromPipeline=$True)]
    $PrevRes = 0)
    Write-Verbose "beta"
    return ($PrevRes+1) 
}

function test3
{
 param(
    [Parameter(Mandatory=$false,ValueFromPipeline=$True)]
    $PrevRes = 0)
    Write-Verbose "omega"
    return ($PrevRes+1)
}

Если вам нужно увеличить $PrevRes значение между командлетами, вы можете использовать переменную из вызывающей области видимости (хотя это несколько анти-шаблон, и я настоятельно рекомендую против этого):

function test1 {
  Write-Host 'alpha'
  $global:PrevRes++
}

function test2 {
  Write-Host 'beta'
  $global:PrevRes++
}

function test3 {
  Write-Host 'omega'
  $global:PrevRes++
}

Тогда используйте как:

PS> test1; test2; test3
alpha
beta
omega
PS> $PrevRes
3

@Mathias правильный, но, судя по вашему вопросу, вы используете Write-Host выводит как ваши фактические возвращаемые значения для пользователя, а не как фактические возвращаемые данные. В этом случае вы действительно хотите сделать что-то подобное. но, как уже было сказано, НЕ используйте Write-Host ни для чего, кроме ранней разработки / отладки скрипта.

Function test1
{
  param(
  [Parameter(Mandatory=$false,ValueFromPipeline=$True)]
  $PrevRes = @())
  $PrevRes += 'alpha'
  return ($PrevRes)
}
Другие вопросы по тегам