-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Win + Russian locale + child_process.exec = ??? #2190
Comments
The issue is that Node.js does always expect UTF-8 output from a child process, but Windows with Russian locale defaults to CP866. WorkaroundIf you only need some UTF-8 output from a Windows shell command, the above issue can be easily worked around by prepending «chcp 65001» to the shell command and thus changing the default codepage of the output from your child process to the node.js-expected UTF-8: 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);
}); You get the correct output in «testfile.txt» then. Workaround issuesIssue 1You still get garbage in console, this cannot be worked around. For example, the following JavaScript 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'); // file system
forker.exec('chcp 65001 | dir', function(err, outstr){
fs.createWriteStream('testfile.txt', {
flags: 'w',
encoding: 'binary'
}).write(outstr);
clog('\n' + outstr);
}); will produce correct «testfile.txt» and the following output: That's because, somewhere deep inside, Node.js expects that UTF-8 output can always be handled by the console, though the actual Windows console with Russian locale does expect CP866 output. That is probably another Node.js issue — separate from expecting UTF-8 output from a shell command. Issue 2It does not help if you run «chcp 65001» before starting Node.js in the same Windows console, intending to change console's codepage. Quite the contrary, it has severe undesired effects on keyboard input, and the console output remains garbage anyway. That is a known misfeature of Windows XP: «chcp 65001» does change the codepage of shell command's output, but does not affect the console. Even the output of chcp itself becomes garbage. |
I have just discovered that both of the two issues of the given workaround are present only when raster fonts are chosen for the Windows console (in its properties). But if «Lucida Console» vector fonts are chosen in the properties of the Windows console, then the console output of Node.js looks correct in any codepage, see the following screenshot: (Though the « |
If the « var clog = console.log;
clog('\nRunning under Node.js version ' + process.versions.node + ' on ' +
process.arch + '-type processor, ' + process.platform + ' platform.');
require('child_process').exec('dir', function(err, outstr){
clog('\n' + outstr);
}); And the default codepage is CP866. |
I've made yet another test in default Windows console (with raster fonts and cp866): It seems that direct output of Unicode strings is fine if the corresponding characters are within CP866. I wonder why All that suddenly becomes more interesting. I should probably open another Node.js issue. |
Not a Node.js issue, but rather a workaround issue: «chcp 65001» actually affects not only the child process, but also somehow affects the current console! So we need to «chcp 866» back (in a console with raster fonts) before we output anything. Totally unexpected! But finally I have some, more correct, workaround for the original issue: 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'); // file system
forker.exec('chcp 65001 | dir', function(err, outstr){
fs.createWriteStream('testfile.txt', {
flags: 'w',
encoding: 'binary'
}).write(outstr);
forker.exec('chcp 866', function(){
clog('\n' + outstr);
});
}); The only remaining problem of a workaround is that two |
@Mithgol Another remark, node does not actually write UTF8 to the console - it writes UCS16 because that is what windows uses internally. I think that when you pick a raster font, windows will try to convert back from unicode to cp866, and that something goes wrong there. Finally, I do not really care about raster font support. Modern windows versions pick a truetype font by default anyway. |
Another solution could be so use |
No, that would not — unless the console fonts are set to vector fonts (“Lucida Console” in Windows XP, probably also “Consolas” in later Windows) beforehand. The raster fonts of Windows console would not play well with UTF-8 encoding (aka codepage 65001). On Windows XP, any Russian text in raster console becomes garbled with that codepage (even the output of And by “any text” I mean “even keyboard input”. On Windows 7, there is no garbage in 65001, but no visible characters also, when you type Russian in a console with raster fonts. And funny thing: the
Yes, that's a Windows bug and not a Node.js problem. The problem is, however, that Node.js does always expect UTF-8 input from (Ideally issue #1772 should be fixed and then
I am not that sure. I've just checked a coworker's Windows 7 workstation and it has raster fonts set in console's settings. The fellow says it has always been like that. |
@Mithgol The problem is that currently we do not support encodings other than utf8 and utf16. And I don't really want to bake all conceivable character encodings into node-core. However maybe we can add an option to exec/spawn to convert data from the current locale to utf8 - that would probably solve the problem. Can you confirm that it is possible to write cyrillic characters to the console using console.log, by writing the appropriate unicode codepoints? |
Yes, I can confirm. It is currently possible to write Cyrillic characters to the Windows console (with both raster and “Lucida Console” fonts), if the console works in default encoding (which is CP866 for consoles in Windows of Russian locale), by using I have already tested it (two days ago) and confirmed with one of the above screenshots; I'll repeat the same image here: This one screenshot was made in raster mode, but |
|
Have you tried the above given script (which contains workarounds for both this issue and #2196)? 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'); // file system
forker.exec('chcp 65001 | dir', function(err, outstr){
fs.createWriteStream('testfile.txt', {
flags: 'w',
encoding: 'binary'
}).write(outstr);
forker.exec('chcp 866', function(){
clog('\n' + outstr);
});
}); If you get any errors (random or not), what are they, what do they look like? |
just use raw data with
|
@Mithgol I get "the system cannot write to the selected device". It happens only if the console font is a raster font tho. |
Why is this issue closed? |
Well, I think you've received a lot of comments and hints, and there was no activity for 7 months. Shoul I reopen it, why? |
Thank you for explaining. |
The comments here just describe possible workarounds, but the issue is still (Node v5.0.0) there. If Windows is supposed to be a first-class citizen in the Node world, this should be fixed. |
@thorn0 This is an archive repo, and the last comment on the issue was more than three years ago. If you think that this is a Node.js (not a setup) problem that still exists with recent Node.js, open an issue at https://github.com/nodejs/node (if it's not there already). |
First, lets try running
dir
in windows cmdline:Then lets run following script in same terminal:
The output will be:
Translated and copied from http://habrahabr.ru/qa/13851/
The text was updated successfully, but these errors were encountered: