Is it possible to synchronously read from stdin in node.js? Because I\'m writing a brainfuck to JavaScript compiler in JavaScript (just for fun). Brainfuck supports a read o
Important: I've just been informed by a Node.js contributor that .fd is undocumented and serves as a means for internal debugging purposes. Therefore, one's code should not reference this, and should manually open the file descriptor with fs.open/openSync
.
In Node.js 6, it's also worth noting that creating an instance of Buffer
via its constructor with new
is deprecated, due to its unsafe nature. One should use Buffer.alloc
instead:
'use strict';
const fs = require('fs');
// small because I'm only reading a few bytes
const BUFFER_LENGTH = 8;
const stdin = fs.openSync('/dev/stdin', 'rs');
const buffer = Buffer.alloc(BUFFER_LENGTH);
fs.readSync(stdin, buffer, 0, BUFFER_LENGTH);
console.log(buffer.toString());
fs.closeSync(stdin);
Also, one should only open and close the file descriptor when necessary; doing this every time one wishes to read from stdin results in unnecessary overhead.
The following code reads sync from stdin. Input is read up until a newline / enter key. The function returns a string of the input with line feeds (\n) and carriage returns (\r) discarded. This should be compatible with Windows, Linux, and Mac OSX. Added conditional call to Buffer.alloc (new Buffer(size) is currently deprecated, but some older versions lack Buffer.alloc.
function prompt(){
var fs = require("fs");
var rtnval = "";
var buffer = Buffer.alloc ? Buffer.alloc(1) : new Buffer(1);
for(;;){
fs.readSync(0, buffer, 0, 1); //0 is fd for stdin
if(buffer[0] === 10){ //LF \n return on line feed
break;
}else if(buffer[0] !== 13){ //CR \r skip carriage return
rtnval += new String(buffer);
}
}
return rtnval;
}
function read_stdinSync() {
var b = new Buffer(1024)
var data = ''
while (true) {
var n = fs.readSync(process.stdin.fd, b, 0, b.length)
if (!n) break
data += b.toString(null, 0, n)
}
return data
}
I've no idea when this showed up but this is a helpful step forward: http://nodejs.org/api/readline.html
var readline = require('readline');
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});
rl.on('line', function (cmd) {
console.log('You just typed: '+cmd);
});
Now I can read line-at-a-time from stdin. Happy days.
I used this workaround on node 0.10.24/linux:
var fs = require("fs")
var fd = fs.openSync("/dev/stdin", "rs")
fs.readSync(fd, new Buffer(1), 0, 1)
fs.closeSync(fd)
This code waits for pressing ENTER. It reads one character from line, if user enters it before pressing ENTER. Other characters will be remained in the console buffer and will be read on subsequent calls to readSync.
Have you tried:
fs=require('fs');
console.log(fs.readFileSync('/dev/stdin').toString());
However, it will wait for the ENTIRE file to be read in, and won't return on \n like scanf or cin.