This works great for me:
const { spawn } = require('child_process')
const shell = spawn('sh',[], { stdio: 'inherit' })
shell.on('close',(code)=>{console.log('[shell] terminated :',code)})
Answer from Adam on Stack OverflowThis works great for me:
const { spawn } = require('child_process')
const shell = spawn('sh',[], { stdio: 'inherit' })
shell.on('close',(code)=>{console.log('[shell] terminated :',code)})
First and foremost, one of the things preventing node from interfacing with other interactive shells is that the child application must keep its "interactive" behavior, even when stdin doesn't look like a terminal. python here knew that its stdin wasn't a terminal, so it refused to work. This can be overridden by adding the -i flag to the python command.
Second, as you well mentioned in the update, you forgot to write a new line character to the stream, so the program behaved as if the user didn't press Enter. Yes, this is the right way to go, but the lack of an interactive mode prevented you from retrieving any results.
Here's something you can do to send multiple inputs to the interactive shell, while still being able to retrieve each result one by one. This code will be resistant to lengthy outputs, accumulating them until a full line is received before performing another instruction. Multiple instructions can be performed at a time as well, which may be preferable if they don't depend on the parent process' state. Feel free to experiment with other asynchronous structures to fulfil your goal.
var cp = require('child_process');
var childProcess = cp.spawn('python', ['-i']);
childProcess.stdout.setEncoding('utf8')
var k = 0;
var data_line = '';
childProcess.stdout.on("data", function(data) {
data_line += data;
if (data_line[data_line.length-1] == '\n') {
// we've got new data (assuming each individual output ends with '\n')
var res = parseFloat(data_line);
data_line = ''; // reset the line of data
console.log('Result #', k, ': ', res);
k++;
// do something else now
if (k < 5) {
// double the previous result
childProcess.stdin.write('2 * + ' + res + '\n');
} else {
// that's enough
childProcess.stdin.end();
}
}
});
childProcess.stdin.write('1 + 0\n');
Videos
Really old question but...
I was looking for something similar, I believe, and found out this.
You can open the REPL (typing node on your terminal) and then load a file.
Like this: .load ./script.js.
Press enter and the file content will be executed. Now everything created (object, variable, function) in your script will be available.
For example:
// script.js
var y = {
name: 'obj',
status: true
};
var x = setInterval(function () {
console.log('As time goes by...');
}, 5000);
On the REPL:
//REPL
.load ./script.js
Now you type on the REPL and interact with the "living code".
You can console.log(y) or clearInterval(x);
It will be a bit odd, cause "As time goes by..." keep showing up every five seconds (or so). But it will work!
You can start a new repl in your Node software pretty easily:
var repl = require("repl");
var r = repl.start("node> ");
r.context.pause = pauseHTTP;
r.context.resume = resumeHTTP;
From within the REPL you can then call pause() or resume() and execute the functions pauseHTTP() and resumeHTTP() directly. Just assign whatever you want to expose to the REPL's context member.
» npm install interactive-console