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