PowerShellで何かを出力する方法


211

バッチファイル内からPowerShellスクリプトを実行しています。スクリプトはWebページをフェッチし、ページのコンテンツが文字列「OK」であるかどうかを確認します。

PowerShellスクリプトは、エラーレベルをバッチスクリプトに返します。

バッチスクリプトは、FTP自動化プログラムであるScriptFTPによって実行されます。エラーが発生した場合は、ScriptFTPでコンソールの完全な出力を管理者に電子メールで送信できます。

PowerShellスクリプトで、「OK」でない場合にWebサイトからの戻り値を出力したいので、エラーメッセージはコンソール出力に含まれ、ステータスメールに含まれます。

私はPowerShellを初めて使用するので、これに使用する出力関数がわかりません。私は3つ見ることができます:

  • 書き込みホスト
  • 書き込み出力
  • 書き込みエラー

Windowsで同等のものに書き込むために使用する正しいものは何でしょうstdoutか?

回答:


197

単純に何かを出力することは、PowerShellが美しさであり、その最大の強みの1つです。たとえば、一般的なHello、World!アプリケーションは1行に削減されます。

"Hello, World!"

文字列オブジェクトを作成し、前述の値を割り当て、コマンドパイプラインの最後の項目として、.toString()メソッドを呼び出し、結果をSTDOUT(デフォルトで)に出力します。美しさ。

その他のWrite-*コマンドは、関連するストリームへのテキストの出力に固有であり、そのような場所があります。


9
それは実際に起こることではありません。これは文字列リテラル式であり、パイプラインで唯一のものです。したがって、と同等"Hello, World!" | Out-Hostです。Out-Host一方、オブジェクトをPowerShellホストに送信して表示し、その実装はホストに依存します。Out-Default実際、コンソールホストはそれらを標準出力ハンドルに送信します(途中でパススルーします)。PowerShell ISEはそれらを出力ペインに表示しますが、他のホストが他のことを完全に実行する場合もあります。
ジョーイ

5
また、オブジェクトは盲目的に文字列に変換されませんが、オブジェクトの処理方法を決定するフォーマッターを通過します。そのGet-ChildItemため、たとえば、出力がテーブル形式で表示され、多くのプロパティ(WMIなど)の結果がデフォルトでFormat-List代わりに表示されます。
ジョーイ

120

この場合、Write-Outputが必要になると思います。

次のようなスクリプトがある場合

Write-Output "test1";
Write-Host "test2";
"test3";

あなたがリダイレクトされた出力、のようなもので、スクリプトを呼び出す場合、その後、yourscript.ps1 > out.txtあなたが取得するtest2画面上にtest1\ntest3\n「out.txtを」に。

"test3"とWrite-Output行は常にテキストに新しい行を追加し、PowerShellでこれを停止する方法がないことに注意してください(つまりecho -n、PowerShellではネイティブコマンドでは不可能です)。(Bashではやや基本的で簡単な)機能が必要なecho -n場合は、samthebestの回答を参照してください。

バッチファイルがPowerShellコマンドを実行する場合、おそらくWrite-Outputコマンドをキャプチャします。コンソールに何を書き込むべきか、何をすべきでないかについてシステム管理者と「長い議論」をしました。これで、スクリプトが正常に実行された、または停止した場合の唯一の情報はWrite-Host「編集」する必要があることに同意しました。スクリプトの作成者であるすべてのものが実行について知る必要がある可能性があります(更新されたアイテム、設定されたフィールドなど)。書き込み出力。このようにして、システム管理者にスクリプトを送信するrunthescript.ps1 >someredirectedoutput.txtと、すべてが問題なければ、彼は簡単に画面で確認できます。次に、「someredirectedoutput.txt」を開発者に送り返します。


9

以下はEcho vs. Write-Hostの良い展示だと思います。test()が信じられそうなほどに単一のintではなく、実際にintの配列を返すことに注目してください。

function test {
    Write-Host 123
    echo 456 # AKA 'Write-Output'
    return 789
}

$x = test

Write-Host "x of type '$($x.GetType().name)' = $x"

Write-Host "`$x[0] = $($x[0])"
Write-Host "`$x[1] = $($x[1])"

上記のターミナル出力:

123
x of type 'Object[]' = 456 789
$x[0] = 456
$x[1] = 789

私はこれを一日中見ることができます...しかし、なぜ $x = test印刷だけでなく印刷123456なぜですか?
not2qubit 2018

7

これらはデフォルトのストリーム(出力とエラー)に書き込むため、シナリオでこれらを使用できます。出力を別のコマンドレットにパイプ処理する場合は、最終的にWrite-Hostで終了するWrite-Outputを使用する必要があります。

この記事では、さまざまな出力オプションについて説明します。PowerShellOは出力用です


1
リンクをありがとう。これは複雑です。Write-hostがある種のエンドポイントまたはフラッシュ機能である場合、私はそれを試してみて、報告します。
Pekka

3
Write-Host "Found file - " + $File.FullName -ForegroundColor Magenta

マゼンタは、 "System.ConsoleColor"列挙子の値の1つにすることができます-ブラック、ダークブルー、ダークグリーン、ダークシアン、ダークレッド、ダークマゼンタ、ダークイエロー、グレー、ダークグレイ、ブルー、グリーン、シアン、レッド、マゼンタ、イエロー、ホワイト。

+ $File.FullNameオプションで、文字列に変数を置く方法を示しています。


2

PowerShellでこれらの厄介な改行を省略することはできません。これを行うスクリプトまたはコマンドレットはありません。

もちろん、Write-Hostはリダイレクト/パイプできないため、まったくナンセンスです。あなたは単にあなた自身のものを書く必要があります:

using System;

namespace WriteToStdout
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args != null)
            {
                Console.Write(string.Join(" ", args));
            }
        }
    }
}

例えば

PS C:\> writetostdout finally I can write to stdout like echo -n
finally I can write to stdout like echo -nPS C:\>

powershell自体でこれを行うことができます。[System.Console] :: Write( "stringy")ただし、Powershellでリダイレクトすることはできません。
Nicholi


1

stdoutと同等のWindowsへの書き込みに使用する正しいものは何でしょうか?

では効果が、非常に残念なことに、両方のWindows PowerShellとPowerShellのコアは、V7.0のように、送信すべてのその6(!)の出力ストリームへの標準出力をするときと呼ばれる外部からのPowerShellの経由、CLI

  • この問題のある動作の説明については、このGitHubの問題を参照してください。下位互換性のために修正されない可能性があります。

  • 実際には、これは、出力を送信するPowerShellストリームが外部の呼び出し元によってstdout出力として認識されることを意味します

    • たとえば、次のコマンドをから実行すると、出力cmd.exeは表示されません。これは、stdoutリダイレクトNULがすべてのPowerShellストリームに等しく適用されるためです。

      • C:\>powershell -noprofile -command "Write-Error error!" >NUL
    • しかし-不思議- あなたがあれば標準エラー出力をリダイレクトし、PowerShellはない stderrにそのエラーストリームを送信するようにしていることを、2>あなたができる選択的エラーストリーム出力をキャプチャします。次の出力'hi'は、成功ストリーム出力ですが、エラーストリーム出力をファイルにキャプチャしていますerr.txt

      • C:\>powershell -noprofile -command "'hi'; Write-Error error!" 2>err.txt

望ましい動作は次のとおりです。

  • PowerShellの成功出力ストリーム(数値1)をstdoutに送信します。
  • 他のすべてのストリームからの出力stderrに送信します。これは、プロセス間に2つの出力ストリームしか存在しないこと前提としています-stdout(標準出力)はデータ、stderr(標準エラー)はエラーメッセージおよびその他すべてのタイプのメッセージ-ステータス情報として- データではありません。

  • 現在、これは尊重されていませんが、コードでこの区別を行うことをお勧めします


PowerShellの内部

  • Write-Hostであるため、表示出力、及びバイパス成功出力ストリームを -のような、その出力はどちらも(直接)変数に捕捉も抑制もリダイレクトすることはできません。

    • その本来の目的は、単にユーザーフィードバックを作成し、シンプルなコンソールベースのユーザーインターフェイス(カラー出力)を作成することでした。

    • 以前にキャプチャまたはリダイレクトできなかったため、PowerShellバージョン5 Write-Hostは新しく導入された情報ストリーム(番号6)に対して行われたため、それ以降、出力をキャプチャしてリダイレクトすること可能Write-Hostです。

  • Write-Error終了しないエラーをエラーストリーム(number )に書き込むためのもの2です。概念的には、エラーストリームはstderrと同等です。

  • Write-Output概念的にはstdoutと同等の成功[出力]ストリーム(数値1)に書き込みます。これはデータ(結果)を書き込むストリームです。

    • ただし、PowerShellの暗黙的な出力機能により、明示的な使用がWrite-Output必要になることはほとんどありません
      • 明示的にキャプチャ、抑制、またはリダイレクトされないコマンドまたは式からの出力は、自動的に成功ストリームに送信されます。例えば、Write-Output "Honey, I'm $HOME"そして"Honey, I'm $HOME"後者はより簡潔であることが、また、より高速なだけでなくと、同等です。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.