mirror of https://github.com/lukechilds/node.git
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.
199 lines
5.6 KiB
199 lines
5.6 KiB
14 years ago
|
## 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]
|
||
|
}
|
||
|
|
||
|
`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.
|
||
|
|
||
|
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) {
|
||
|
util.print('stdout: ' + data);
|
||
|
});
|
||
|
|
||
|
ls.stderr.on('data', function (data) {
|
||
|
util.print('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) {
|
||
|
util.print('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) {
|
||
|
util.print(data);
|
||
|
});
|
||
|
|
||
|
grep.stderr.on('data', function (data) {
|
||
|
util.print('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.on('data', function (data) {
|
||
|
if (/^execvp\(\)/.test(data.asciiSlice(0,data.length))) {
|
||
|
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) {
|
||
|
util.print('stdout: ' + stdout);
|
||
|
util.print('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)`
|