Powershell:如果是管道化的,则将输出抑制到控制台

Powershell:如果是管道化的,则将输出抑制到控制台,powershell,return,output,suppress,Powershell,Return,Output,Suppress,我正在Powershell上编写一个搜索工具,遇到了一个无法抑制函数返回的问题,它总是打印到控制台。 为了清楚起见,我做了一些较小的测试函数 Function test1 { param( [Parameter(Mandatory=$false,ValueFromPipeline=$True)] $PrevRes = 0) write-host "alfa" return ($PrevRes+1) } Function test2 { param(

我正在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实现这一点

如果不涉及客户的任何行动,任何解决方案都是有用的


提前谢谢你回答这个问题

是否有一种方法可以在函数本身中确定返回值是否是管道化的

有。检查
$MyInvocation
自动变量,并比较
PipelineLength
PipelinePosition
属性:

if($MyInvocation.PipelinePosition -lt $MyInvocation.PipelineLength){
    return $PrevRes + 1
}
原始答案如下


非常简单的解决方案:

不要在脚本中使用。 正如名称所示,它将直接向宿主应用程序写入内容

如果出于调试目的需要保留这些语句,请改用或cmdlet:

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

如果需要在cmdlet之间增加
$PrevRes
值,可以使用调用范围中的变量(尽管这有点反模式,我强烈建议不要这样做):

然后使用类似于:

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

回答问题

是否有一种方法可以在函数本身中确定返回值是否是管道化的

有。检查
$MyInvocation
自动变量,并比较
PipelineLength
PipelinePosition
属性:

if($MyInvocation.PipelinePosition -lt $MyInvocation.PipelineLength){
    return $PrevRes + 1
}
原始答案如下


非常简单的解决方案:

不要在脚本中使用。 正如名称所示,它将直接向宿主应用程序写入内容

如果出于调试目的需要保留这些语句,请改用或cmdlet:

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

如果需要在cmdlet之间增加
$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)
}

@Mathias是正确的,但从问题的外观来看,您使用的是
Write Host
输出作为用户的实际返回值,而不是实际返回数据。在这种情况下,你真的想做更多类似的事情。但正如前面所说的,除了脚本的早期开发/调试之外,不要使用Write Host

Function test1
{
  param(
  [Parameter(Mandatory=$false,ValueFromPipeline=$True)]
  $PrevRes = @())
  $PrevRes += 'alpha'
  return ($PrevRes)
}

非常感谢您的回复,但我很抱歉,也许我的问题没有自我解释。我必须使用写主机,因为它向用户提供数据。我真正想问的是,是否有一种方法可以在函数本身中确定返回值是否是管道化的?我需要为计算增加$PrevRes值,但当它不再是管道时,我不想将其输出到屏幕。因此,在最开始,我只需要alfa beta和omega,末尾没有数字。@SokIsKedu我不确定“如果返回值是流水线的”是什么意思-在PowerShell中,函数发出0个或多个对象,最后一个在return语句之后。如果管道中的下一件事是另一个函数,那么对象将被发送到it,否则将返回给被调用方如果您的客户“不知道如何使用它”,那么他为什么会要求您交付它?我想问的是有没有抑制返回值的方法?比如,如果我将它传递给另一个函数,我可以用它进行计算,但如果不是,我不希望返回值显示在屏幕上。客户对powershell和pipeline有一部分熟悉,但如果需要添加更多内容,他将不会满意。哦,我在标题中犯了一个错误,错过了“不”一词。它应该像Powershell一样:如果不是管道,则将输出限制到控制台非常感谢您的回答,但很抱歉,可能我的问题不是自我解释的。我必须使用写主机,因为它向用户提供数据。我真正想问的是,是否有一种方法可以在函数本身中确定返回值是否是管道化的?我需要为计算增加$PrevRes值,但当它不再是管道时,我不想将其输出到屏幕。因此,在最开始,我只需要alfa beta和omega,末尾没有数字。@SokIsKedu我不确定“如果返回值是流水线的”是什么意思-在PowerShell中,函数发出0个或多个对象,最后一个在return语句之后。如果管道中的下一件事是另一个函数,那么对象将被发送到it,否则将返回给被调用方如果您的客户“不知道如何使用它”,那么他为什么会要求您交付它?我想问的是有没有抑制返回值的方法?比如,如果我将它传递给另一个函数,我可以用它进行计算,但如果不是,我不希望返回值显示在屏幕上。客户对powershell和pipeline有一部分熟悉,但如果需要添加更多内容,他将不会满意。哦,我在标题中犯了一个错误,错过了“不”一词。它应该像Powershell:将输出压缩到conso