5

「a.ps1」というスクリプト呼び出しがあります。

write-host "hello host"
"output object"

スクリプトを呼び出して出力オブジェクトを取得したいのですが、標準出力も抑制したいのですが、

$result = .\a.ps1
# Don't want anything printed to the console here

ヒントはありますか?

4

3 に答える 3

6

これを行う簡単な方法は本当にありません。

回避策は、同じ名前の関数を定義することにより、Write-Hostのデフォルトの動作をオーバーライドすることです。

function global:Write-Host() {}

これは非常に柔軟です。そして、それは上記の私の単純な例で機能します。ただし、何らかの理由で、適用したい実際のケースでは機能しません(おそらく、呼び出されたスクリプトが署名されており、セキュリティ上の理由から、呼び出し元が任意に動作を変更することはできません)。

私が試したもう1つの方法は、基盤となるコンソールのstdoutを次のように変更することでした。

$stringWriter = New-Object System.IO.StringWriter
[System.Console]::SetOut($stringWriter)
[System.Console]::WriteLine("HI") # Outputs to $stringWriter
Write-Host("HI") # STILL OUTPUTS TO HOST :(

しかし、ご覧のとおり、それでも機能しません。

于 2013-01-23T07:03:07.387 に答える
0

出力オブジェクトie "output object"はに出力されstandard outputます。したがって、標準出力を抑制したくないと思います。コンソールに何も出力したくない場合は、Write-Hostすべてのストリーム(stdout、stderr、warning、verbose)をバイパスするため、使用しないでください。 、debug)を実行し、ホストに直接表示します。現在、ホスト出力をリダイレクトするための簡単なメカニズムはありません。

ところで、後で表示されたくないのに、なぜコンソールに「hellohost」を書き込む必要があるのでしょうか。

于 2013-01-23T02:47:56.993 に答える
0

OK、少し掘り下げました。次を使用できます。

次のリンク

そして、やります:

$result = .\1.ps1 | Select-WriteHost -Quiet
$result[1]

次に、変数の2番目のオブジェクトを選択します。

別の説明

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」に感謝します:)

于 2013-01-24T10:31:08.713 に答える