PowerShell でパイプを使ってコマンドを記述しても、そこを流れるのがテキスト/バイナリデータではなくオブジェクト。なのに、.NET Frameworkに対応していない従来のコマンドも普通にコマンド打つだけで実行できてしまう。
はて、従来のテキストベースのコマンドをPowerShell上でパイプで記述するとどうなるのだろ? ためしにnetpbmを使って以下のコマンドを打つと、ppmtojpegでエラー。
PS C:¥> bmptopnm bitmap | ppmtojpeg > bitmap.jpeg
C:¥Program Files¥GnuWin32¥bin¥bmptopnm.exe: Windows BMP, 1024x768x32
C:¥Program Files¥GnuWin32¥bin¥bmptopnm.exe: WRITING PPM IMAGE
C:¥Program Files¥GnuWin32¥bin¥ppmtojpeg.exe: EOF / read error reading a one-byte sample
で、
PS C:¥> $a = bmptoppm bitmap.bmp
C:¥Program Files¥GnuWin32¥bin¥bmptoppm.exe: Windows BMP, 1024x768x32
C:¥Program Files¥GnuWin32¥bin¥bmptoppm.exe: WRITING PPM IMAGE
PS C:¥> $a.gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
PS C:¥> $a[0].gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
bmptopnmの出力はSystem.Stringクラスオブジェクトの配列に変換され、でまたテキストに戻されppmtojpegに渡されるということになっているようです。
で、どうもこのStringオブジェクトに変換する際にデータはUnicode化され、バイナリデータであるbmptopnmの出力は書き換わっているっぽい。
pnmtopnmを使ってテキストフォーマットにすれば
問題なく扱えるのでしょうが、Unicode化されるのでだめ 。
bmptopnm|pnmtopnm -plain
としてもpnmtopnmに渡される時点でデータは壊れてるし。
PowerShellは好きなんですが、こういう用途には使うなということですね。
[参考]
[2008/3/10] 追記
Comments