有没有办法设置变量以将输出放置到 stdout 或 null? [英] Is there a way to set a variable up to place output to stdout or null?

查看:37
本文介绍了有没有办法设置变量以将输出放置到 stdout 或 null?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的代码中设置一个变量,最终定义我是否会看到一些输出.

  • "hello" 写入标准输出
  • 你好">$null 抑制输出

我的想法是这样的:

$debugOutputSwitch = $true$outputVar = $nullif ($debugOutputSwitch){ $outputVar = **STDOUT** }...写主持人无论如何我想要的东西"我在 STDOUT 上可能不想要的东西">$输出变量

如果这个总体思路是可行的,那么 STDOUT 就是我要寻找的

如果这个想法完全错误......好吧......那我就迷路了

解决方案

您想阅读的内容是 Powershell 中的输出流和重定向.这包括有关所有不同输出流的信息以及如何使用内置结构控制它们的相关性.就像有 Write-HostWrite-Output cmdlet 一样,还有其他几个 cmdlet 控制要写入的流.

关于输出流

总共有 6 个流.记下它们的编号,因为这些流标识符用于控制要重定向的流:

  • 1 - 成功流 - 当沿着 Powershell 管道.这是默认"流,但也可以使用 Write-Output 写入.
  • 2 - 错误流 - 应将错误写入此流.可以使用 Write-Error 写入,并附有更多错误信息.
  • 3 - 警告流 - 用于写入警告信息.可以使用 Write-Warning 写入.
  • 4 - 详细流 - 用于编写详细输出.默认情况下不显示,但可以通过设置 $VerbosePreference = "Continue",或通过在函数或脚本上使用 [CmdletBinding()] 属性并传入 -Verbose 标志.使用 Write-Verbose 写入详细流.
  • 5 - 调试流 - 用于写入调试流,并可选择触发断点.默认情况下不显示或触发断点,但可以通过 $DebugPreference 变量,或通过在脚本或函数上使用 [CmdletBinding()] 属性和使用 -Debug 标志.您可以使用 Write-Debug cmdlet 写入调试流.
  • 6 - 信息流 - 可以由 Write-Host 写入.这是控制台主机输出,不是管道的一部分.

重定向流

您也可以使用重定向运算符将其他流重定向到成功流.上面的每个流都有一个与之关联的数字.这是每个流的数字表示.

重定向操作符如下:

  • > - 将成功流重定向到文件(覆盖)
  • #> - 将 # 流重定向到文件(例如 2> somefile.txt)
  • >> - 将成功流重定向到文件(附加,您也可以像覆盖文件运算符一样使用编号流)
  • >&1 - 将 任何 流重定向到 success 流(请注意,与其他重定向运算符不同,您只能重定向到成功流.使用其他流标识符将导致错误).

另请注意,您可以使用 * 代替流编号,这将同时重定向所有流.>

以下是一些将输出从一个流重定向到另一个流的示例(如果您熟悉它,它有点 UNIX-y):

# 写入成功流到文件写输出这是文件的一些文本">.\somefile.txt# 将错误流写入文件(你必须首先写错误发生了一些错误"2>.\somefile.txt# 将所有错误输出重定向到成功流$myErrorOutput = 写错误我的错误输出"2>&1# 将所有脚本输出流附加到单个文件中Get-OutputFromAllStreams.ps1 *>>一些文件.txt

同时输出到文件和管道

您也可以同时将输出流重定向到文件和管道,使用 Tee-Object cmdlet:

$myString = "我的输出" |Tee-Object -FilePath .\somefile.txt

显示如何使用不同Write- cmdlet 的示例函数

注意以下函数是如何使用 [CmdletBinding()] 属性修饰的.这是使 -Verbose-Debug 开关工作而无需您自己定义它们的关键.

[CmdletBinding()]函数写不同的输出{# 默认情况下这些都是可见的,但只有输出流通过管道传递写输出输出流"写警告警告流"写错误错误流"写主机信息流"# 默认情况下这些是不可见的,但会在传递 `-Verbose` 或 `-Debug` 标志时写入# 也可以手动设置 $VerbosePreference 或 $DebugPreference 变量来控制这个不带参数写详细详细流"写调试调试流"}

使用 -Verbose-Debug 开关调用上述函数以查看行为有何不同,也可以不使用任何标志调用它.

如果确实需要,将输出重定向到 $null

如果有您不想看到的输出或出于其他原因使用 Write- cmdlet 写入 VerboseDebug 流不是一个选项,您仍然可以将输出重定向到 $null 或使用 Out-Null cmdlet.回想一下这个答案顶部的编号流,它们将在此处引用:

使用重定向

# 不要忘记 *>重定向所有流,可能是你想要的写输出成功流">$null写错误'错误流' 2>$null写警告'警告流' 3>$null写详细'详细流' 4>$null写调试'调试流' 5>$null写主机'信息流(是的,你可以抑制/重定向我)' 6>$null

使用Out-Null

请记住,您可以通过将输出重定向到 &1 来将其他流重定向到成功流.

#记住,要在管道上传递信息# 它必须首先出现在成功流上# 别忘了 *>重定向所有流,可能是你想要的写输出'成功流' |出空写错误'错误流'2>&1 |出空写警告'警告流' 3>&1 |出空写详细'详细流' 4>&1 |出空写-调试调试流"5>&1 |出空写主机'信息流(是的,你可以抑制/重定向我)' 6>&1 |出空

将整个命令输出重定向到 Write- cmdlet

您可以轻松地将命令或 cmdlet 的所有输出通过管道传输到 Write- cmdlet 之一.我将使用前面示例中提供的 Write-DifferentOutputs,但这适用于您运行的任何 cmdlet、脚本或命令:

Write-DifferentOutputs *>&1 |写详细

以上只会在 $VerbosePreference = $Continue 或您将 -Verbose 作为参数传递给脚本或函数时显示命令输出.

总结中

在您最初的问题中,您试图重新发明一个 Powershell 已经很好地支持的轮子.我建议您学习如何使用不同的 Write-Output 每个流的 cmdlet,尤其是学习如何使用 Write-Warning, Write-Verbose, Write-ErrorWrite-Debugcmdlet.

I would like to set up a variable in my code that would ultimately define if I'll see some output or not.

  • "hello" writes to stdout
  • "hello" > $null supresses output

My idea is something like this:

$debugOutputSwitch = $true
$outputVar = $null
if ($debugOutputSwitch){ $outputVar = **STDOUT** }
...
Write-Host "Something I want out anyway"
"Something I might not want on STDOUT" > $outputVar

If this general idea is a way to go, then STDOUT is what I'm looking for

If this idea is completely wrong...well...then I'm lost

解决方案

What you want to read up on are output streams and redirection in Powershell. This includes information on all of the different output streams and how to control their relevance using built-in constructs. Just like there are the Write-Host and Write-Output cmdlets, there are also several others that control which stream to write to.

About the Output Streams

There are 6 streams in total. Make note of their numbers, because these stream identifiers are used to control which streams to redirect:

  • 1 - Success Stream - This stream is used when passing information along the Powershell Pipeline. This is the "default" stream, but can also be written to with Write-Output.
  • 2 - Error Stream - Errors should be written to this stream. Can be written to with Write-Error, accompanied by further error information.
  • 3 - Warning Stream - Used to write warning information. Can be written to with Write-Warning.
  • 4 - Verbose Stream - Used to write verbose output. Does not display by default but can be made to display by either setting $VerbosePreference = "Continue", or by using the [CmdletBinding()] attribute on a function or script and passing in the -Verbose flag. Write to the verbose stream with Write-Verbose.
  • 5 - Debug Stream - Used to write to the debug stream, and optionally trigger a breakpoint. Does not display or trigger a breakpoint by default, but can be controlled with the $DebugPreference variable, or by using the [CmdletBinding()] attribute on a script or function and using the -Debug flag. You can write to the debug stream by using the Write-Debug cmdlet.
  • 6 - Information Stream - Can be written to by Write-Host. This is the console host output and is not part of the pipeline.

Redirecting Streams

You can use redirection operators to redirect other streams to the success stream as well. Each stream above has a number associated with it. This is the numeric representation of each stream.

The redirection operators are as follows:

  • > - Redirect success stream to file (overwrite)
  • #> - Redirect the # stream to file (e.g. 2> somefile.txt)
  • >> - Redirect success stream to file (appends, you can also use a numbered stream as with the overwrite file operator)
  • >&1 - Redirect any stream to success stream (note that unlike the other redirection operators you can only redirect to the success stream. Using other stream identifiers will result in an error).

Also note that in place of a stream number, you can use * which will redirect all streams at the same time.

Here are some examples of redirecting output from one stream to another (if you're familiar with it, it's somewhat UNIX-y):

# Write success stream to file
Write-Output "Here is some text for a file" > .\somefile.txt

# Write error stream to file (you have to first
Write-Error "Some error occurred" 2> .\somefile.txt

# Redirect all error output to the success stream
$myErrorOutput = Write-Error "My error output" 2>&1

# Append all script output streams to a single file
Get-OutputFromAllStreams.ps1 *>> somefile.txt

Output to a File and the Pipeline Simultaneously

You can redirect the output stream to a file and the pipeline at the same time as well, using the Tee-Object cmdlet:

$myString = "My Output" | Tee-Object -FilePath .\somefile.txt

Sample function to show how to use the different Write- cmdlets

Note how the following function is decorated with the [CmdletBinding()] attribute. This is key in making the -Verbose and -Debug switches work without you having to define them yourself.

[CmdletBinding()]
function Write-DifferentOutputs {
  # These all visible by default but only the output stream is passed down the pipeline
  Write-Output "Output stream"
  Write-Warning "Warning stream"
  Write-Error "Error stream"
  Write-Host "Information stream"

  # These are not visible by default, but are written when the `-Verbose` or `-Debug` flags are passed
  # You can also manually set the $VerbosePreference or $DebugPreference variables to control this without parameters
  Write-Verbose "Verbose stream"
  Write-Debug "Debug stream"
}

Call the above function with the -Verbose or -Debug switches to see how the behavior differs, and also call it with neither flag.

Redirecting output to $null if you really need to

If there is output that you never want to see or for some other reason using the Write- cmdlets to write to the Verbose or Debug streams isn't an option, you can still redirect output to $null or make use of the Out-Null cmdlet. Recall the numbered streams at the top of this answer, they will be referenced here:

Using redirection

# Don't forget that *> redirects ALL streams, and may be what you want
Write-Output 'Success Stream' > $null
Write-Error 'Error Stream' 2> $null
Write-Warning 'Warning Stream' 3> $null
Write-Verbose 'Verbose Stream' 4> $null
Write-Debug 'Debug Stream' 5> $null
Write-Host 'Information Stream (yes you can suppress/redirect me)' 6> $null

Using Out-Null

Remember, you can redirect other streams to the success stream by redirecting the output to &1.

# Remember, to pass information on the pipeline
# it MUST be on the success stream first

# Don't forget that *> redirects ALL streams, and may be what you want
Write-Output 'Success Stream' | Out-Null
Write-Error 'Error Stream' 2>&1 | Out-Null
Write-Warning 'Warning Stream' 3>&1 | Out-Null
Write-Verbose 'Verbose Stream' 4>&1 | Out-Null
Write-Debug 'Debug Stream' 5>&1 | Out-Null
Write-Host 'Information Stream (yes you can suppress/redirect me)' 6>&1 | Out-Null

Redirecting whole command outputs to Write- cmdlets

You can easily pipe all output of a command or cmdlet to one of the Write- cmdlets. I'll use the Write-DifferentOutputs provided earlier in my example below, but this will work with any cmdlet, script, or command you run:

Write-DifferentOutputs *>&1 | Write-Verbose

What the above will do is only show the command output if $VerbosePreference = $Continue, or if you passed -Verbose as an argument to your script or function.

In Summarium

In your original question, you are attempting to reinvent a wheel that Powershell already supports fairly well. I would suggest that you learn how to make use of the different Write-Output cmdlets for each stream and especially learn how to make use of the Write-Warning, Write-Verbose, Write-Error, and Write-Debug cmdlets.

这篇关于有没有办法设置变量以将输出放置到 stdout 或 null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆