【问题标题】:Best way to return values from a function that writes to STDOUT从写入 STDOUT 的函数返回值的最佳方法
【发布时间】:2020-01-03 02:22:12
【问题描述】:

我有一些辅助函数写入 STDOUT 以进行日志记录。其中一些函数会向调用者返回一个值,但会返回函数的整个输出。

我怎样才能让我的函数写入 STDOUT 向调用者返回一个值,而返回值不会被函数调用期间发出的所有 STDOUT 污染?

我正在寻找某种设计模式或最佳实践。

考虑这个脚本:

Function a
{
    Write-Output "In Function a"
    $a = 4
    return $a   
}

$b = a

Write-Output "Outside function: `$b is $b"

输出是

Outside function: $b is In Function a 4

但我希望输出是:

In Function a
$b is 4

【问题讨论】:

  • 顺便说一句:在 PowerShell 内部,技术上没有 stdout(标准输出);等价于 成功输出流 - 请参阅about_Redirection

标签: function powershell powershell-2.0


【解决方案1】:

在 PowerShell all 中返回函数内未捕获的输出,而不仅仅是 return 的参数。来自documentation

在 PowerShell 中,每个语句的结果都会作为输出返回,即使没有包含 return 关键字的语句。

函数长这样没关系:

function Foo {
  'foo'
}

或者像这样:

function Foo {
  'foo'
  return
}

或者像这样:

function Foo {
  return 'foo'
}

无论哪种方式,它都会返回字符串foo

为了防止输出被返回,你可以

  • 写入主机或其他ouptput streams 之一(取决于您要创建的输出类型):

    Function a {
      Write-Host 'some text'
      Write-Verbose 'verbose message'
      Write-Information 'info message'   # requires PowerShell v5 or newer
      $a = 4
      return $a
    }
    

    旁注:Write-Information 在引入 information stream 时在 PowerShell v5 之前不可用,从该版本开始,Write-Host 也写入该流而不是直接写入主机控制台。

  • 在变量中捕获输出或将其“分配”给$null

    Function a {
      $var = Write-Output 'some text'
      $null = Write-Output 'some text'
      $a = 4
      return $a
    }
    
  • 或将输出重定向到$null:

    Function a {
      Write-Output 'some text' | Out-Null
      Write-Output 'some text' >$null
      $a = 4
      return $a
    }
    

【讨论】:

  • 不错;值得一提的是另一种抑制输出的方法:$null = 'some text',这通常是最快的。
【解决方案2】:

另一种方法:

  1. 在您的函数中,通过 Write-Information 进行日志记录。
  2. 在调用范围内,调用子表达式内的函数,并将子表达式的信息流重定向到stdout。请务必将函数的返回值分配给变量,否则它也会转到标准输出。

例如

function bar() {
  Write-Information "Hello from bar()"
  return 4
}

$($x = bar) 6>&1

Write-Output "in main `$x = $x"

如果您使用的是旧版本的 powershell 并且无法使用 Write-Information,则同样的方法适用于 Write-Verbose。在这种情况下,您将重定向为4>&1。使用详细时,您将得到难看的黄色/黑色和“VERBOSE”文本,除非您将整个脚本的标准输出重定向到文件中,在这种情况下,VERBOSE: 标记将被省略。

【讨论】:

    猜你喜欢
    • 2010-09-26
    • 2017-05-22
    • 2010-09-07
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    相关资源
    最近更新 更多