2

I'm making an interactive CLI in node (and blessed.js) that spawns child processes every couple of seconds to run some Python scripts. These scripts modify a set of JSON files that the CLI pulls from.

The problem is that the CLI must be able to accept input from the user at all times, and when these child processes are spawned, the stdin of the CLI/parent process appears to be blocked and it looks like the Python scripts are executing in the foreground. Here's the code I'm using to run the Python scripts:

const { spawn } = require("child_process");

function execPythonScript(args) {
    return spawn("python3", args, { stdio: "ignore" });
}

execPythonScript(["path_to_script.py"]);

I've also tried running the script as a background process, i.e. execPythonScript(["path_to_script.py", "&"]), but to no avail. Any ideas?

Thanks in advance!

UPDATE:

I'm starting to suspect this is an issue with blessed and not child-process, since I've exhausted all relevant methods (and their arguments) for spawning non-blocking background processes, and the problem still persists.

Each blessed instance uses process.stdin for input by default, but I figured it's possible that the stdin stream gets used up by the child processes, even though I'm spawning them with stdio set to "ignore". So I tried using ttys and instantiating blessed.screen to read from the active terminal (/dev/tty) instead of /dev/stdin:

const ttys = require("ttys");

screen = blessed.screen({
    input: ttys.stdin, // Instead of process.stdin
    smartCSR: true
});

But it's still blocking...

  • Which OS are you using? There is slightly different behavior among them sometimes which may be effecting you. I'm guessing Linux or Mac because you're trying to use &, but still. Also, [execFile](https://nodejs.org/api/child_process.html#child_process_child_process_execfile_file_args_options_callback) may work for you in this case, though I'm not 100% sure. – l3l_aze Nov 07 '18 at 04:28
  • 1
    @l3l_aze I'm using Mac OS. I tried execFile but the process still runs in the foreground. – Jonathan Shobrook Nov 07 '18 at 16:11
  • Have you tried using spawn with detached set to true to make a subprocess, and then use subprocess.unref() as in the [options.detached](https://nodejs.org/api/child_process.html#child_process_options_detached) documentation? – l3l_aze Nov 08 '18 at 22:36
  • 1
    Yes I have, with no luck. I believe that method is only used to let the parent process exit independently of the child. – Jonathan Shobrook Nov 10 '18 at 00:17

1 Answers1

2

You also need to detach the process:

spawn("python3", args, { stdio: "ignore", detached: true })

This is a useful primer.

Daniel Rothig
  • 621
  • 2
  • 10