16

I am using child_process.spawn() to start a script from my Node.JS application running on Ubuntu. As far as I know, standard forked or spawned *nix processes don't generally die when the parent dies, but when spawning processes from Node.JS, they seem to get killed when my application crashes, or is aborted with ctrl-c etc.

Why is this and is there a way around this? I can't seem to find any obvious option in the child_process API.

My application starts some quite long-running tasks that should run in the background, and if my node server crashes or is restarted for some other reason I don't want to interrupt the tasks, instead I want the node server to come back up and gracefully resume monitoring the progress of those running tasks.

JHH
  • 8,567
  • 8
  • 47
  • 91

1 Answers1

27

you need to set the detached option

If the detached option is set, the child process will be made the leader of a new process group. This makes it possible for the child to continue running after the parent exits.

var child = spawn('prg', [], {
   detached: true,
   stdio: [ 'ignore', out, err ]
 });
Johny
  • 739
  • 1
  • 9
  • 16
  • 3
    Thanks a lot. Don't know HOW I managed to miss that. For reference, if anyone else finds this answer useful, here's from the manual: https://nodejs.org/api/child_process.html#child_process_options_detached – JHH Jun 08 '15 at 12:43
  • 1
    I have one concern though. The manual - and your code - specifically says that stdio must be directed elsewhere than to the parent process (which is default) for the process to continue in the background. However, I found that even if I didn't specify any stdio options, the process did infact continue even after I killed my node server. I am not sure what exactly is going on here, but maybe ['ignore', 'ignore', 'ignore'] is a wise option nonetheless. – JHH Jun 08 '15 at 12:45
  • 2
    not specifying stdio will default to stdio: ['pipe', 'pipe', 'pipe']... which means the pipes are available through ChildProcess.stdin, ChildProcess.stdout and ChildProcess.stderr(in this case **I think** you must read from stdout and stderr otherwise your childprocess may hang)... if you don't need to interact with the childprosess's stdio from parent process, then you can just use 'ignore' which will forward any output from your childprocess to /dev/null – Johny Jun 08 '15 at 17:24
  • Thanks for the additional info. Appreciated. I've got it working well now. – JHH Jun 09 '15 at 20:48
  • But how would you then get actual data into the childprocess? If you use "ignore" for stdin, then the child.stdin property is undefined, and we can't write to it manually. – Herman Dec 23 '21 at 10:46