PowerShellの出力ストリームと型

本日 PowerShell の記事を投稿したばっかりですが、こいつ結構面白いぞと思い始めたので、色々と調査しながらブログ記事にしていきたいと思います。というかただの実験ノートです。

出力ストリーム

以下のサイトを参考にしています。

新年一発目のエントリなのでPowerShellの基本的なことについて書きます。 PowerShellの基本的なことがわかってなかったシリーズ第8弾でもあります。 このエントリを書く動機 Google等でWrite-Host Write-Output 違いなワードで検索すると非常にアレな感じだったのでもう少しまともにした...

Write-HostWrite-Output

この2つのコマンドレットは違うようだ、という内容。そもそもですが、「PowerShell はオブジェクトを渡すのにそれをどうやってコンソールに出力しているんだ?」という疑問から始まってこのトピックについて調査しています。少なくともオブジェクトは「型」ですのでそれをコンソールに出力するんだよな?それじゃあ stdout とか stderr に相当するものはどうなってるの?という疑問です。

記事によるとどうやら Write-Host は出力をコンソールに出すだけらしいです。なので ストリームを流れずパイプで渡せません。一方で Write-Output は出力ストリームに流すというもので、パイプで渡せます。コンソール出力と出力ストリームは別物なので Write-Output hoge とやっても hoge と出ないはずなのですが、コマンド末端に行き場を失ったオブジェクトは整形されて表示されるというものらしいです。つまり Write-Host で出力された値をいじることはできないということになります。さて実際にやってみましょう。っとそのまえに、echo がどのコマンドレットのエイリアスなのかまずは調査です。

PS > gal echo
Alias           echo -> Write-Output

ということなので Write-Output の方だとわかりました。では比較です。方法ですが、とりあえず適当な文字列を表示しパイプで渡す。その先に where でフィルタして「表示するな」と指示してみます。

PS > write-host hoge | ?{$false}
hoge
PS > write-output hoge | ?{$false}
PS >

ということで、調査どおりに Write-Host の方はパイプを通らないのでその後のフィルタに関係なく表示がコンソールに出てきました。

Write-Host のオプション

表示用コマンドレットというだけあって、表示用オプションがあるらしいです。Microsoft のヘルプを見ましょう。例えばこんな実行結果になります。

基本的に [type] を付けます。キャストだと思えば良いのかな。

PS > [int]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType

intInt32 のことなのか。

具体的な値に .GetType() とすることで型名を取得可能です。

PS > $a=1
PS > $a.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType

整数同士の割り算は、割り切れるならサイズの大きい方の整数型割り切れないなら Double になるようです。

PS > 1/1
0
PS > (1/1).gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType
PS > ([int64]1/1).gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int64                                    System.ValueType
PS > 1/2
0.5
PS > (1/2).gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Double                                   System.ValueType

そういえば、適当に遊んでたら PowerShell という型を見つけましたwwww

PS > [powershell]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    PowerShell                               System.Object