You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
5.7 KiB

## Child Processes
Node provides a tri-directional `popen(3)` facility through the `ChildProcess`
class.
It is possible to stream data through the child's `stdin`, `stdout`, and
`stderr` in a fully non-blocking way.
To create a child process use `require('child_process').spawn()`.
Child processes always have three streams associated with them. `child.stdin`,
`child.stdout`, and `child.stderr`.
`ChildProcess` is an `EventEmitter`.
### Event: 'exit'
`function (code, signal) {}`
This event is emitted after the child process ends. If the process terminated
normally, `code` is the final exit code of the process, otherwise `null`. If
the process terminated due to receipt of a signal, `signal` is the string name
of the signal, otherwise `null`.
See `waitpid(2)`.
### child.stdin
A `Writable Stream` that represents the child process's `stdin`.
Closing this stream via `end()` often causes the child process to terminate.
### child.stdout
A `Readable Stream` that represents the child process's `stdout`.
### child.stderr
A `Readable Stream` that represents the child process's `stderr`.
### child.pid
The PID of the child process.
Example:
var spawn = require('child_process').spawn,
grep = spawn('grep', ['ssh']);
console.log('Spawned child pid: ' + grep.pid);
grep.stdin.end();
### child_process.spawn(command, args=[], [options])
Launches a new process with the given `command`, with command line arguments in `args`.
If omitted, `args` defaults to an empty Array.
The third argument is used to specify additional options, which defaults to:
{ cwd: undefined,
env: process.env,
customFds: [-1, -1, -1],
setsid: false
}
`cwd` allows you to specify the working directory from which the process is spawned.
Use `env` to specify environment variables that will be visible to the new process.
With `customFds` it is possible to hook up the new process' [stdin, stout, stderr] to
existing streams; `-1` means that a new stream should be created. `setsid`,
if set true, will cause the subprocess to be run in a new session.
Example of running `ls -lh /usr`, capturing `stdout`, `stderr`, and the exit code:
var util = require('util'),
spawn = require('child_process').spawn,
ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
ls.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
ls.on('exit', function (code) {
console.log('child process exited with code ' + code);
});
Example: A very elaborate way to run 'ps ax | grep ssh'
var util = require('util'),
spawn = require('child_process').spawn,
ps = spawn('ps', ['ax']),
grep = spawn('grep', ['ssh']);
ps.stdout.on('data', function (data) {
grep.stdin.write(data);
});
ps.stderr.on('data', function (data) {
console.log('ps stderr: ' + data);
});
ps.on('exit', function (code) {
if (code !== 0) {
console.log('ps process exited with code ' + code);
}
grep.stdin.end();
});
grep.stdout.on('data', function (data) {
console.log(data);
});
grep.stderr.on('data', function (data) {
console.log('grep stderr: ' + data);
});
grep.on('exit', function (code) {
if (code !== 0) {
console.log('grep process exited with code ' + code);
}
});
Example of checking for failed exec:
var spawn = require('child_process').spawn,
child = spawn('bad_command');
child.stderr.setEncoding('utf8');
child.stderr.on('data', function (data) {
if (/^execvp\(\)/.test(data)) {
console.log('Failed to start child process.');
}
});
See also: `child_process.exec()`
### child_process.exec(command, [options], callback)
High-level way to execute a command as a child process, buffer the
output, and return it all in a callback.
var util = require('util'),
exec = require('child_process').exec,
child;
child = exec('cat *.js bad_file | wc -l',
function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});
The callback gets the arguments `(error, stdout, stderr)`. On success, `error`
will be `null`. On error, `error` will be an instance of `Error` and `err.code`
will be the exit code of the child process, and `err.signal` will be set to the
signal that terminated the process.
There is a second optional argument to specify several options. The default options are
{ encoding: 'utf8',
timeout: 0,
maxBuffer: 200*1024,
killSignal: 'SIGTERM',
cwd: null,
env: null }
If `timeout` is greater than 0, then it will kill the child process
if it runs longer than `timeout` milliseconds. The child process is killed with
`killSignal` (default: `'SIGTERM'`). `maxBuffer` specifies the largest
amount of data allowed on stdout or stderr - if this value is exceeded then
the child process is killed.
### child.kill(signal='SIGTERM')
Send a signal to the child process. If no argument is given, the process will
be sent `'SIGTERM'`. See `signal(7)` for a list of available signals.
var spawn = require('child_process').spawn,
grep = spawn('grep', ['ssh']);
grep.on('exit', function (code, signal) {
console.log('child process terminated due to receipt of signal '+signal);
});
// send SIGHUP to process
grep.kill('SIGHUP');
Note that while the function is called `kill`, the signal delivered to the child
process may not actually kill it. `kill` really just sends a signal to a process.
See `kill(2)`