javascriptterminalelectron

Electron JS: spawn() works fine with "python --version" but with "python" I don't get any output


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?


Solution

  • 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);