I'm using Electron JS and trying to execute a command in a child process using spawn() from the child_process module.
When I run the command python --version
, it correctly outputs the version of Python in the child process. However, when I run just python
, the process seems to start but doesn't output anything, and the behavior appears inconsistent.
Here is a simplified version of my code:
const { spawn } = require('child_process');
const child = spawn('python', [], { shell: true });
child.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
child.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
child.on('close', (code) => {
console.log(`Child process exited with code ${code}`);
});
What I expect:
Running python should launch the interactive Python REPL and provide output.
What actually happens:
When I run python --version
, it works fine.
When I run just python
, there is no output or REPL interaction visible in my app.
Additional Details:
Electron version: v34.0.0
Node.js version: v23.6.0
IDE: Visual Studio Code
OS: Windows 11 24H2
What could be causing this issue? Do I need to set up the child process differently to handle REPL or interactive commands in Electron?
Your code is indeed correct, the only thing you've missed is that running a Python process as a spawn with no arguments will make it search arguments for a script file. To force interactive mode, you should add -i
to the argument list (note that on a regular terminal it works fine without this).
This NodeJS code snippet seems to solve your problem:
const { spawn } = require("child_process");
const py = spawn("python", ["-i"]);
py.on("close", code => console.log("Closed: " + code));
py.stdout.on("data", data => {
console.log(data.toString());
})
py.stderr.on("data", data => {
console.log(data.toString());
})
// Some example commands
const commands = [
"2 + 2",
"print('Test')",
"print(3 + 2)",
"5 - 8",
"exit(1234)"
]
var i = 0;
var input = setInterval(function() {
py.stdin.write(commands[i] + '\n');
i++;
if (i >= commands.length) clearInterval(input);
}, 500);