也许在 PowerShell 中无法做到这一点。
如果我有文件verboseTest.ps1
[CmdletBinding()] # CmdletBinding attribute enables -verbose flag
Param()
Write-Verbose 'verbose test'
如果我调用 .\verboseTest.ps1
,我看不到任何预期的内容。
如果我调用 .\verboseTest.ps1 -Verbose
我会看到输出。
VERBOSE: verbose test outer
正如预期的那样。
但是如果我调用 .\verboseTest.ps1 4>&1
我不会。详细流丢失。
现在,Info 的行为完全不同了。
我有文件 infoTest.ps1
并且它的行为正常。
[CmdletBinding()] # Add CmdletBinding attribute
Param()
Write-Information 'info test outer'
如果我调用 .\infoTest.ps1
,我看不到任何预期的内容。
如果我调用 .\infoTest.ps1 -InformationAction 'Continue'
(类似于 -Verbose
标志),它会成功并输出 info test external
到控制台。
如果我调用.\infoTest.ps1 6>&1
,它也会将info test external
输出到控制台!因此,“信息”流的行为与“详细”流完全不同。
信息流的行为是有道理的。写入信息命令写入流,我可以按照我认为合适的方式重定向或查看它。而“冗长”则不然!我必须在输出中显示它才能重定向它?难道我做错了什么?这有什么意义?
我是否必须启用详细首选项才能重定向输出?如果是这样,我可以在方法内部执行此操作还是可以在全局 session 范围内更改它?
最佳答案
不幸的是,详细流(流编号 4
)在未显式打开时不仅静默,而且没有数据写入它。
也就是说,Write-Verbose
语句是有效的无操作[1],除非 -Verbose
已传递或首选项变量 $VerbosePreference
设置为 Continue
。
PowerShell 的默认静默输出流 - 详细 (4
)、调试 (5
) 和信息 (6
) - < strong>信息流是唯一的异常(exception):Write-Information
语句总是写入它,无论它是否碰巧被静音。
将首选项变量 $VerbosePreference
设置为 Continue
将为当前作用域和任何子作用域中的所有命令打开详细输出 - 但有一个重要异常(exception):
高级函数在模块中实现,只能看到$VerbosePreference
的全局实例 当从脚本调用时;相比之下,二进制cmdlet不受到影响。
this GitHub issue 中讨论了这种高度有问题的行为。
您可以按如下方式解决该问题:
# Create a script-local copy of the global parameter-defaults
# hashtable.
# Note: If you want to clear the global presets, call .Clear()
# after cloning.
$PSDefaultParameterValues = $PSDefaultParameterValues.Clone()
# Preset the -Verbose switch for all commands that support it.
$PSDefaultParameterValues['*:Verbose'] = $true
# ... call commands, which will behave as if -Verbose had been passed.
[1] 但是,cmdlet 仍然被调用,这意味着您传递给它的参数会被求值,因此假设静默Write-Verbose 仍然是可能的
调用会产生副作用,例如将可扩展字符串作为包含具有副作用的子表达式 ($(...)
) 的消息传递时。
关于powershell - 捕获详细流而不启用 -Verbose,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56798054/