[英]PowerShell: how to capture (or suppress) write-host
我有一个脚本调用“a.ps1”:
write-host "hello host"
"output object"
我想调用脚本并获取输出对象,但我还希望抑制标准输出:
$result = .\a.ps1
# Don't want anything printed to the console here
任何提示?
真的没有简单的方法可以做到这一点。
解决方法是通过定义具有相同名称的函数来覆盖Write-Host的默认行为:
function global:Write-Host() {}
这非常灵活。 它适用于我上面简单的例子。 但是,由于某些未知原因,它不适用于我想要应用的实际情况(可能因为被调用的脚本已签名,并且出于安全原因,它不允许调用者任意更改行为)。
我尝试的另一种方法是通过以下方式修改底层Console的标准输出:
$stringWriter = New-Object System.IO.StringWriter
[System.Console]::SetOut($stringWriter)
[System.Console]::WriteLine("HI") # Outputs to $stringWriter
Write-Host("HI") # STILL OUTPUTS TO HOST :(
但正如你所看到的,它仍然无效。
输出对象即"output object
”输出到standard output
。 所以我认为你不想压制标准输出。 如果您不希望在控制台上打印任何内容,请不要使用Write-Host
因为它会绕过所有流(stdout,stderr,warning,verbose,debug)并直接显示给主机。 目前还没有我想知道的重定向主机输出的简单机制。
顺便说一句,如果你不想在以后看到它,你为什么需要在控制台上写“hello host”?
好的,我做了一点挖掘。 您可以使用:
并做:
$result = .\1.ps1 | Select-WriteHost -Quiet
$result[1]
然后选择变量中的第二个对象:
您也可以以不会将Write-Host更改为Write-Output的方式更改脚本,只需“删除”Write-Host。
完成...
function Remove-WriteHost
{
[CmdletBinding(DefaultParameterSetName = 'FromPipeline')]
param(
[Parameter(ValueFromPipeline = $true, ParameterSetName = 'FromPipeline')]
[object] $InputObject,
[Parameter(Mandatory = $true, ParameterSetName = 'FromScriptblock', Position = 0)]
[ScriptBlock] $ScriptBlock
)
begin
{
function Cleanup
{
# Clear out our proxy version of Write-Host
remove-item function:\write-host -ea 0
}
function ReplaceWriteHost([string] $Scope)
{
Invoke-Expression "function ${scope}:Write-Host { }"
}
Cleanup
# If we are running at the end of a pipeline, need to
# immediately inject our version into global scope,
# so that everybody else in the pipeline uses it.
#
# This works great, but it is dangerous if we don't
# clean up properly.
if($pscmdlet.ParameterSetName -eq 'FromPipeline')
{
ReplaceWriteHost -Scope 'global'
}
}
process
{
# If a scriptblock was passed to us, then we can declare
# our version as local scope and let the runtime take it
# out of scope for us. It is much safer, but it won't
# work in the pipeline scenario.
#
# The scriptblock will inherit our version automatically
# as it's in a child scope.
if($pscmdlet.ParameterSetName -eq 'FromScriptBlock')
{
. ReplaceWriteHost -Scope 'local'
& $scriptblock
}
else
{
# In a pipeline scenario, just pass input along
$InputObject
}
}
end
{
Cleanup
}
}
$result = .\1.ps1 | Remove-WriteHost
感谢“latkin”的原始功能:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.