
Node.JS公式ブログ(昨日(11月25日)
で 、ノードの新しいバージョンが番号0.6.3で
発表されました。 変更はそれほど重要ではありません:多数のエラーと欠陥が修正されました。
私はこれを面白くない誕生日プレゼントだと思いました(偶然、11月25日に33歳になりました)。 ただし、同じ日に、「
node.jsから呼び出されたWindowsコマンドの出力を受け入れる方法は?」という質問
をします 。 「私はWindows XPで一連の実験を開始しました。その結果、Windowsでエンコードを操作しているとき
に2つのノードエラーが発見されました。
まず、
require( 'child_process')。Exec(...)メソッドを使用してコマンドが呼び出されると、Nodeは
UTF-8でエンコードされた出力を期待しますが、Russified Windowsシステムのコマンド(
dirなど )はCP866でエンコードされたテキストを出力します。
第二に、子コンソールプロセスがコンソールエンコーディングを変更した場合、親ノードプロセスのコンソールエンコーディング(特に、
console.logメソッドを使用した出力)にも影響します-それらは同じコンソール
または何かを持っていることが
わかります同じ精神。
そして今、いくつかの詳細。
私が見つけた2つのバグのうち最初のバグは、最も単純なスクリプトを実行して、子プロセスを呼び出し、その出力をリテラル形式でファイルに書き込む場合、遭遇するのは難しくありません。
var fs = require('fs');
ファイル内のロシア文字の代わりにナンセンスがあります。
sdevalexが正しく
示唆したように 、この問題の回避策があり
ます。Windowsの 「chcp」コマンドを使用して、呼び出されたプロセスのエンコーディングを変更するだけです。 これを念頭に置いてコンパイルされたスクリプトは、目的のタイプのコマンド出力をテキストファイルに表示します。
var forker = require('child_process'); var fs = require('fs');
ただし、この回避策では、ファイルだけでなくコンソールにも結果を出力する場合、2番目のエラーが発生する可能性があります。このスクリプトを記述するのに十分です。
var clog = console.log; clog('\nRunning under Node.js version ' + process.versions.node + ' on ' + process.arch + '-type processor, ' + process.platform + ' platform.'); var forker = require('child_process'); var fs = require('fs');
つまずくことができます。 そして、奇妙なことに、つまずかないことができます。 コンソールでラスターフォントを使用するかベクターフォントを使用するか(Windows XPではLucida Consoleフォントで再生されます)、つまり、使い慣れたコンソールプロパティダイアログボックスの2番目のタブの中央の設定に依存します。
![[コンソールプロパティウィンドウ]](https://habrastorage.org/getpro/habr/post_images/e61/b3e/636/e61b3e6367d26c3d0a3a4a684e6e4a2d.png)
私が覚えている限りでは、Windows XPはデフォルトでコンソールでビットマップフォントを使用します(間違っている場合は修正してください)。 したがって、自分でこの設定を変更していない場合、上記のスクリプトは必要なテキストをファイル(「testfile.txt」)に出力し、魅力のないものがコンソールに出力されます。
![[コンソールのスクリーンショット]](https://habrastorage.org/getpro/habr/post_images/8aa/d7c/8ba/8aad7c8ba95255487d254e7c6c933973.gif)
これはすべて、ラスターコンソールで「chcp」コマンドがコマンドによって表示されるテキストのエンコード
のみを変更するためです。 ビットマップフォントはそれに適応できないため、コンソールでの「chcp」コマンドの出力でさえ見苦しくなります。
![[chcpスクリーンショット]](https://habrastorage.org/getpro/habr/post_images/973/3a8/c90/9733a8c9052610492e1e1dd3f6b497b1.gif)
コンソールがベクターフォント(Lucida Console)でテキストを表示するように構成されている場合、
「chcp」コマンドを使用してコンソールで事前に設定したものは何でも、スクリプト出力が正しいように見えるため、この問題に気付かないでしょう
:![[ベクターコンソールのスクリーンショット]](https://habrastorage.org/getpro/habr/post_images/8ff/8eb/d34/8ff8ebd34a8cce2d453fbd62ae380c16.gif)
この段階で、髪の毛は頭に逆らって立ち、ゆっくりと動きます。 開発者(ベクターコンソールを使用している場合)が、自分と他の多くのユーザー(ラスターコンソール)で正常に機能する10行のコードでスクリプトを作成できる、異常に潜んでいる問題があることが明らかだからです。予防的に。
しかし、この問題は何ですか?
JavaScriptでは文字列がユニコードであり、WindowsコンソールではCP866でエンコードされているため、おそらくNodeはWindowsコンソールへの出力に対応していませんか? そして、ここにありますが、これはそうではありません-コンソールへの簡単なテスト出力で簡単に証明できます:
![[テストのスクリーンショット]](https://habrastorage.org/getpro/habr/post_images/d41/8b1/d42/d418b1d4247dc47220c87a68af227d0c.gif)
おそらく、出力文字がCP866エンコーディングを超えると、ノードはゴミに切り替わりますか? いいえ。これを確認するには、
「 \ u2248 \ u0422 \ u0435 \ u0441 \ u0442 」の行を印刷するだけで十分です。 文字
「 \ u2248 」自体は疑問符に置き換えられますが、行の残りの部分は影響を受けません。
別の推測が当てはまることが
わかります。ラスターコンソールのこのゴミは、コードページの変更に関するメッセージではなく、コマンド
「chcp 65001」によって表示されるゴミと同じ性質のものです。 さらに
、彼が呼ばれるの
はまさにそれです 。 このコマンドを子プロセスで指定し
、dirコマンドで表示されるテキストのエンコードを変更することを意図しました
-ただし
、chcpコマンドは親コンソールに
も影響しました!
これを完全に実証するには、簡単なテストで十分です。
![[別のテストのスクリーンショット]](https://habrastorage.org/getpro/habr/post_images/5e0/311/8b1/5e03118b15ba18b524072867b0637d3e.gif)
ご覧のとおり、子プロセスからの「chcp 65001」は親プロセスのコンソールウィンドウで動作します(コマンド「chcp 866」が発行され、デフォルトのCP866コードページが返されるまで動作します)。
この新しいエラーを理解することで、以前に見つかったエラーを回避するより良い方法を発見できます。
「dir」コマンドの前に「chcp 65001」を呼び出すと、「chcp 866」を再度呼び出して、
「dir」コマンドによって発行されたテキストを表示する前にコンソールを元の状態に戻す必要があります
。 var clog = console.log; clog('\nRunning under Node.js version ' + process.versions.node + ' on ' + process.arch + '-type processor, ' + process.platform + ' platform.'); var forker = require('child_process'); var fs = require('fs');
このスクリプトはすでに、テストファイルだけでなくコンソールにも完璧なテキストをシームレスに出力できます。
![[別のテストのスクリーンショット]](https://habrastorage.org/getpro/habr/post_images/edd/3e6/c96/edd3e6c961148fdc9c0a4162df9d43d2.gif)
この回避策は、その完璧さにも
かかわらず 、克服できないアーキテクチャ上の欠陥があります。もちろん、2つの
.exec()呼び出しは非同期であるため、それらの間でコンソールはしばらくの間異常モードのままになります。
両方のエラーはGitHubを介してNode開発者に報告されました:
donnerjack13589は昨日
問題2190を作成し、今日は
問題2196を作成しました。