Как принять вывод Windows-команды, вызванной из node.js?

Создадим файл «index.js» нижеследующего вида:
require('child_process').exec('dir', function(err, outstr){
   console.log(outstr);
});

После этого вывод команды «node ./», запущенной из русифицированной Windows, будет нижеследующим:
 ??? ? ?????? U ????? ????? USBSTICK
 ?????? ????? ??: 467B-0CBE

 ???????? ????? U:\Fido\Soft\_Sources\node

24.11.2011  15:12    <DIR>          .
24.11.2011  15:12    <DIR>          ..
25.11.2011  09:36               522 index.js
               1 ????            522 ????
               2 ?????  17?412?767?744 ???? ??????

Примерно то же самое получим и в файле, если вести запись не в консоль, а в тестовый файл:
var fs = require('fs'); // file system

require('child_process').exec('dir', function(err, outstr){
   fs.createWriteStream('testfile.txt', {
      flags: 'w',
      encoding: 'binary'
   }).write(outstr);
});

Спрашивается: как быть и что делать, чтобы получить от процесса текст в произвольной кодировке? Очевидно, Node.js не ожидает, что команда «dir» выплёвывает текст в CP866, и оттого недетски обламывается. Надобно заставить Node.js принять русский текст:
U:\Fido\Soft\_Sources\node>dir
 Том в устройстве U имеет метку USBSTICK
 Серийный номер тома: 467B-0CBE

 Содержимое папки U:\Fido\Soft\_Sources\node

24.11.2011  15:12    <DIR>          .
24.11.2011  15:12    <DIR>          ..
25.11.2011  09:37               522 index.js
               1 файлов            522 байт
               2 папок  17 412 767 744 байт свободно

Как этого добиться?
25 ноября 2011 в 09:52
3
Mithgol 110,2

отсортировано по дате по оценке
ответы (3)

+4
sdevalex #
Есть команда chcp, которая меняет кодировку терминала в Windows. А вообще лучше конечно не париться, а юзать хорошие вещи в хороших серверных OS.
Спасибо за предложение отказаться от Windows, но подлинно кросс-платформенный скрипт, конечно, не может ему последовать. Команда «chcp» действительно решает проблему: для переключения консоли в UTF-8 достаточно подать команду «chcp 65001». Скрипт приобретает нижеследующий вид:
var forker = require('child_process');
var fs = require('fs'); // file system

forker.exec('chcp 65001 | dir', function(err, outstr){
   fs.createWriteStream('testfile.txt', {
      flags: 'w',
      encoding: 'binary'
   }).write(outstr);
});

В тестовом файле в итоге получаем вывод команды «dir», представленный в кодировке UTF-8. Это наглядное свидетельство того, что он же содержится и в переменной «outstr».
Mithgol, 25 ноября 2011 в 12:54
exec и кроссплатформенность очень противоположны (хотя можно писать обертку под каждую ос, но вроде в Windows терминальных утилит не так много, как в Linux к примеру). sdevalex, 25 ноября 2011 в 16:16
+1
mark_ablov #
node-iconv не помогает?
Вы вон про ту обёртку вокруг libiconv? Дык ить libconv же нету в Windows, если не прибегать к cygwin и другим подобным костылям. Mithgol, 25 ноября 2011 в 12:49
+1
donnerjack13589 #
Спасибо.

Откомментировал там.
Mithgol, 26 ноября 2011 в 08:56
Также выложил блогозапись во блоге Node.JS, а не то «Q&A» не все ведь читают на Хабрахабре. Mithgol, 26 ноября 2011 в 14:45

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.