process
是全局对象,可以在任意位置访问,是 EventEmitter 的实例。javascript
当没有新的异步的操做等待处理时,Node 正常状况下退出时会返回状态码 0
。下面的状态码表示其余状态:css
1
未捕获的致命异常-Uncaught Fatal Exception - 有未捕获异常,而且没有被域或 uncaughtException
处理函数处理。2
- Unused (保留)3
JavaScript解析错误-Internal JavaScript Parse Error - JavaScript的源码启动 Node 进程时引发解析错误。很是罕见,仅会在开发 Node 时才会有。4
JavaScript评估失败-Internal JavaScript Evaluation Failure - JavaScript的源码启动 Node 进程,评估时返回函数失败。很是罕见,仅会在开发 Node 时才会有。5
致命错误-Fatal Error - V8 里致命的不可恢复的错误。一般会打印到 stderr ,内容为: FATAL ERROR
6
Non-function 异常处理-Non-function Internal Exception Handler - 未捕获异常,内部异常处理函数不知为什么设置为on-function,而且不能被调用。7
异常处理函数运行时失败-Internal Exception Handler Run-Time Failure - 未捕获的异常, 而且异常处理函数处理时本身抛出了异常。例如,若是 process.on('uncaughtException')
或 domain.on('error')
抛出了异常。8
- Unused保留. 以前版本的 Node, 8 有时表示未捕获异常。9
- 参数非法-Invalid Argument - 多是给了未知的参数,或者给的参数没有值。10
运行时失败-Internal JavaScript Run-Time Failure - JavaScript的源码启动 Node 进程时抛出错误,很是罕见,仅会在开发 Node 时才会有。12
无效的 Debug 参数-Invalid Debug Argument - 设置了参数--debug
和/或 --debug-brk
,可是选择了错误端口。>128
信号退出-Signal Exits - 若是 Node 接收到致命信号,好比SIGKILL
或 SIGHUP
,那么退出代码就是128
加信号代码。这是标准的 Unix 作法,退出信号代码放在高位。当进程准备退出时触发。此时已经没有办法阻止从事件循环中推出。所以,你必须在处理函数中执行同步操做。这是一个在固定事件检查模块状态(好比单元测试)的好时机。回调函数有一个参数,它是进程的退出代码。html
监听 exit
事件的例子:java
process.on('exit', function(code) { // do *NOT* do this setTimeout(function() { console.log('This will not run'); }, 0); console.log('About to exit with code:', code); });
当 node 清空事件循环,而且没有其余安排时触发这个事件。一般来讲,当没有进程安排时 node 退出,可是 'beforeExit' 的监听器能够异步调用,这样 node 就会继续执行。node
'beforeExit' 并非明确退出的条件,process.exit()
或异常捕获才是,因此不要把它当作'exit' 事件。除非你想安排更多的工做。linux
当一个异常冒泡回到事件循环,触发这个事件。若是给异常添加了监视器,默认的操做(打印堆栈跟踪信息并退出)就不会发生。npm
监听 uncaughtException
的例子:json
process.on('uncaughtException', function(err) { console.log('Caught exception: ' + err); }); setTimeout(function() { console.log('This will still run.'); }, 500); // Intentionally cause an exception, but don't catch it. nonexistentFunc(); console.log('This will not run.');
注意,uncaughtException
是很是简略的异常处理机制。vim
尽可能不要使用它,而应该用 domains 。若是你用了,每次未处理异常后,重启你的程序。数组
不要使用 node.js 里诸如 On Error Resume Next
这样操做。每一个未处理的异常意味着你的程序,和你的 node.js 扩展程序,一个未知状态。盲目的恢复意味着 任何事情 均可能发生
你在升级的系统时拉掉了电源线,而后恢复了。可能10次里有9次没有问题,可是第10次,你的系统可能就会挂掉。
当进程接收到信号时就触发。信号列表详见标准的 POSIX 信号名,如 SIGINT、SIGUSR1 等
监听 SIGINT
的例子:
// Start reading from stdin so we don't exit. process.stdin.resume(); process.on('SIGINT', function() { console.log('Got SIGINT. Press Control-D to exit.'); });
在大多数终端程序里,发送 SIGINT
信号的简单方法是按下 信号Control-C
。
注意:
SIGUSR1
node.js 接收这个信号开启调试模式。能够安装一个监听器,但开始时不会中断调试。SIGTERM
和 SIGINT
在非 Windows 系统里,有默认的处理函数,退出(伴随退出代码 128 + 信号码
)前,重置退出模式。若是这些信号有监视器,默认的行为将会被移除。SIGPIPE
默认状况下忽略,能够加监听器。SIGHUP
当 Windowns 控制台关闭的时候生成,其余平台的相似条件,参见signal(7)。能够添加监听者,Windows 平台上 10 秒后会无条件退出。在非 Windows 平台上,SIGHUP
的默认操做是终止 node,可是一旦添加了监听器,默认动做将会被移除。 SIGHUP
is to terminate node, but once a listener has been installed itsSIGTERM
Windows 不支持, 能够被监听。SIGINT
全部的终端都支持,一般由CTRL+C
生成(可能须要配置)。当终端原始模式启用后不会再生成。SIGBREAK
Windows 里,按下 CTRL+BREAK
会发送。非 Windows 平台,能够被监听,可是不能发送或生成。SIGWINCH
- 当控制台被重设大小时发送。Windows 系统里,仅会在控制台上输入内容时,光标移动,或者可读的 tty在原始模式上使用。SIGKILL
不能有监视器,在全部平台上无条件关闭 node。SIGSTOP
不能有监视器。Windows 不支持发送信号,可是 node 提供了不少process.kill()
和 child_process.kill()
的模拟:
0
能够查找运行中得进程SIGINT
, SIGTERM
, 和 SIGKILL
会引发目标进程无条件退出。一个 Writable Stream
执向 stdout
(on fd 1
).
例如: console.log
的定义:
console.log = function(d) { process.stdout.write(d + '\n'); };
process.stderr
和 process.stdout
和 node 里的其余流不一样,他们不会被关闭(end()
将会被抛出),它们不会触发 finish
事件,而且写是阻塞的。
检查 Node 是否运行在 TTY 上下文中,从process.stderr
, process.stdout
, 或 process.stdin
里读取 isTTY
属性。
$ node -p "Boolean(process.stdin.isTTY)" true $ echo "foo" | node -p "Boolean(process.stdin.isTTY)" false $ node -p "Boolean(process.stdout.isTTY)" true $ node -p "Boolean(process.stdout.isTTY)" | cat false
更多信息参见 the tty docs。
一个指向 stderr (on fd 2
)的可写流。
process.stderr
和 process.stdout
和 node 里的其余流不一样,他们不会被关闭(end()
将会被抛出),它们不会触发 finish
事件,而且写是阻塞的。
一个指向 stdin (on fd 0
)的可读流。
如下例子:打开标准输入流,并监听两个事件:
process.stdin.setEncoding('utf8'); process.stdin.on('readable', function() { var chunk = process.stdin.read(); if (chunk !== null) { process.stdout.write('data: ' + chunk); } }); process.stdin.on('end', function() { process.stdout.write('end'); });
process.stdin
能够工做在老模式里,和 v0.10 以前版本的 node 代码兼容。
更多信息参见Stream compatibility.
在老的流模式里,stdin流默认暂停,必须调用 process.stdin.resume()
读取。能够调用 process.stdin.resume()
切换到老的模式。
若是开始一个新的工程,最好选择新的流,而不是用老的流。
包含命令行参数的数组。第一个元素是'node',第二个参数是 JavaScript 文件的名字,第三个参数是任意的命令行参数。
// print process.argv process.argv.forEach(function(val, index, array) { console.log(index + ': ' + val); });
将会生成:
$ node process-2.js one two=three four 0: node 1: /Users/mjr/work/node/process-2.js 2: one 3: two=three 4: four
开启当前进程的执行文件的绝对路径。
例子:
/usr/local/bin/node
启动进程所需的 node 命令行参数。这些参数不会在 process.argv
里出现,而且不包含 node 执行文件的名字,或者任何在名字以后的参数。这些用来生成子进程,使之拥有和父进程有相同的参数。
例子:
$ node --harmony script.js --version
process.execArgv 的参数:
['--harmony']
process.argv 的参数:
['/usr/local/bin/node', 'script.js', '--version']
这将致使 node 触发 abort 事件。会让 node 退出并生成一个核心文件。
改变当前工做进程的目录,若是操做失败抛出异常。
console.log('Starting directory: ' + process.cwd()); try { process.chdir('/tmp'); console.log('New directory: ' + process.cwd()); } catch (err) { console.log('chdir: ' + err); }
返回当前进程的工做目录
console.log('Current directory: ' + process.cwd());
包含用户环境的对象,参见 environ(7).
这个对象的例子:
{ TERM: 'xterm-256color', SHELL: '/usr/local/bin/bash', USER: 'maciej', PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin', PWD: '/Users/maciej', EDITOR: 'vim', SHLVL: '1', HOME: '/Users/maciej', LOGNAME: 'maciej', _: '/usr/local/bin/node' }
你能够写入这个对象,可是不会改变当前运行的进程。如下的命令不会成功:
node -e 'process.env.foo = "bar"' && echo $foo
这个会成功:
process.env.foo = 'bar'; console.log(process.env.foo);
使用指定的 code 结束进程。若是忽略,将会使用 code 0
使用失败的代码退出:
process.exit(1);
Shell 将会看到退出代码为1.
进程退出时的代码,若是进程优雅的退出,或者经过 process.exit()
退出,不须要指定退出码。
设定 process.exit(code)
将会重写以前设置的 process.exitCode
。
注意:这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。
获取进程的群组标识(参见 getgid(2))。获取到得时群组的数字 id,而不是名字。
if (process.getgid) { console.log('Current gid: ' + process.getgid()); }
注意:这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。
设置进程的群组标识(参见 setgid(2))。能够接收数字 ID 或者群组名。若是指定了群组名,会阻塞等待解析为数字 ID 。
if (process.getgid && process.setgid) { console.log('Current gid: ' + process.getgid()); try { process.setgid(501); console.log('New gid: ' + process.getgid()); } catch (err) { console.log('Failed to set gid: ' + err); } }
注意:这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。
获取进程的用户标识(参见 getuid(2))。这是数字的用户 id,不是用户名
if (process.getuid) { console.log('Current uid: ' + process.getuid()); }
注意:这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。
设置进程的用户标识(参见setuid(2))。接收数字 ID或字符串名字。果指定了群组名,会阻塞等待解析为数字 ID 。
if (process.getuid && process.setuid) { console.log('Current uid: ' + process.getuid()); try { process.setuid(501); console.log('New uid: ' + process.getuid()); } catch (err) { console.log('Failed to set uid: ' + err); } }
注意:这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。
返回进程的群组 iD 数组。POSIX 系统没有保证必定有,可是 node.js 保证有。
注意:这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。
设置进程的群组 ID。这是受权操做,全部你须要有 root 权限,或者有 CAP_SETGID 能力。
列表能够包含群组 IDs,群组名,或者二者都有。
注意:这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。
读取 /etc/group ,并初始化群组访问列表,使用成员所在的全部群组。这是受权操做,全部你须要有 root 权限,或者有 CAP_SETGID 能力。
user
是用户名或者用户 ID, extra_group
是群组名或群组 ID。
当你在注销权限 (dropping privileges) 的时候须要注意. 例子:
console.log(process.getgroups()); // [ 0 ] process.initgroups('bnoordhuis', 1000); // switch user console.log(process.getgroups()); // [ 27, 30, 46, 1000, 0 ] process.setgid(1000); // drop root gid console.log(process.getgroups()); // [ 27, 30, 46, 1000 ]
一个编译属性,包含 NODE_VERSION
.
console.log('Version: ' + process.version);
一个属性,包含了 node 的版本和依赖.
console.log(process.versions);
打印出来:
{ http_parser: '1.0', node: '0.10.4', v8: '3.14.5.8', ares: '1.9.0-DEV', uv: '0.10.3', zlib: '1.2.3', modules: '11', openssl: '1.0.1e' }
一个包含用来编译当前 node 执行文件的 javascript 配置选项的对象。它与运行 ./configure 脚本生成的 "config.gypi" 文件相同。
一个可能的输出:
{ target_defaults: { cflags: [], default_configuration: 'Release', defines: [], include_dirs: [], libraries: [] }, variables: { host_arch: 'x64', node_install_npm: 'true', node_prefix: '', node_shared_cares: 'false', node_shared_http_parser: 'false', node_shared_libuv: 'false', node_shared_v8: 'false', node_shared_zlib: 'false', node_use_dtrace: 'false', node_use_openssl: 'true', node_shared_openssl: 'false', strict_aliasing: 'true', target_arch: 'x64', v8_use_snapshot: 'true' } }
发送信号给进程. pid
是进程id,而且 signal
是发送的信号的字符串描述。信号名是字符串,好比'SIGINT' 或 'SIGHUP'。若是忽略,信号会是 'SIGTERM'.更多信息参见 Signal 事件 和 kill(2) .
若是进程没有退出,会抛出错误。信号 0
能够用来测试进程是否存在。
注意,虽然这个这个函数名叫process.kill
,它真的仅是信号发射器,就像kill
系统调用。信号发射能够作其余事情,不只是杀死目标进程。
例子, 给本身发信号:
process.on('SIGHUP', function() { console.log('Got SIGHUP signal.'); }); setTimeout(function() { console.log('Exiting.'); process.exit(0); }, 100); process.kill(process.pid, 'SIGHUP');
注意: 当 Node.js 接收到 SIGUSR1 信号,它会开启 debugger 调试模式, 参见Signal Events.
当前进程的 PID
console.log('This process is pid ' + process.pid);
获取/设置(Getter/setter) 'ps' 中显示的进程名。
使用 setter 时,字符串的长度由系统指定,可能会很短。
在 Linux 和 OS X 上,它受限于名称的长度加上命令行参数的长度,由于它会覆盖参数内存(argv memory)。
v0.8 版本容许更长的进程标题字符串,也支持覆盖环境内存,可是存在潜在的不安全和混乱(很难说清楚)。
当前 CPU 的架构:'arm'、'ia32' 或者 'x64'.
console.log('This processor architecture is ' + process.arch);
运行程序所在的平台系统 'darwin'
, 'freebsd'
, 'linux'
, 'sunos'
or 'win32'
console.log('This platform is ' + process.platform);
返回一个对象,描述了 Node 进程所用的内存情况,单位为字节。
var util = require('util'); console.log(util.inspect(process.memoryUsage()));
将会生成:
{ rss: 4935680, heapTotal: 1826816, heapUsed: 650472 }
heapTotal
and heapUsed
refer to V8's memory usage.
callback
{Function}一旦当前事件循环结束,调用回到函数。
这不是 setTimeout(fn, 0)
的简单别名,这个效率更高。在任何附加 I/O 事件在子队列事件循环中触发前,它就会运行。
console.log('start'); process.nextTick(function() { console.log('nextTick callback'); }); console.log('scheduled'); // Output: // start // scheduled // nextTick callback
在对象构造后,在 I/O 事件发生前,你又想改变附加事件处理函数时,这个很是有用。
function MyThing(options) { this.setupOptions(options); process.nextTick(function() { this.startDoingStuff(); }.bind(this)); } var thing = new MyThing(); thing.getReadyForStuff(); // thing.startDoingStuff() gets called now, not before.
要保证你的函数必定是 100% 同步执行,或者 100% 异步执行。例子:
// WARNING! DO NOT USE! BAD UNSAFE HAZARD! function maybeSync(arg, cb) { if (arg) { cb(); return; } fs.stat('file', cb); }
这个 API 很是危险. 若是你这么作:
maybeSync(true, function() { foo(); }); bar();
不清楚foo()
或 bar()
哪一个先执行。
更好的方法:
function definitelyAsync(arg, cb) { if (arg) { process.nextTick(cb); return; } fs.stat('file', cb); }
注意:nextTick 队列会在彻底执行完毕以后才调用 I/O 操做。所以,递归设置 nextTick 的回调就像一个 while(true);
循环同样,将会阻止任何 I/O 操做的发生。
设置或读取进程文件的掩码。子进程从父进程继承掩码。若是mask
参数有效,返回旧的掩码。不然,返回当前掩码。
var oldmask, newmask = 0022; oldmask = process.umask(newmask); console.log('Changed umask from: ' + oldmask.toString(8) + ' to ' + newmask.toString(8));
返回 Node 已经运行的秒数。
返回当前进程的高分辨时间,形式为 [seconds, nanoseconds]
数组。它是相对于过去的任意事件。该值与日期无关,所以不受时钟漂移的影响。主要用途是能够经过精确的时间间隔,来衡量程序的性能。
你能够将以前的结果传递给当前的 process.hrtime()
,会返回二者间的时间差,用来基准和测量时间间隔。
var time = process.hrtime(); // [ 1800216, 25 ] setTimeout(function() { var diff = process.hrtime(time); // [ 1, 552 ] console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]); // benchmark took 1000000527 nanoseconds }, 1000);
require.main
的备选方法。不一样点,若是主模块在运行时改变,require.main
可能会继续返回老的模块。能够认为,这二者引用了同一个模块。
Alternate way to retrieverequire.main
.The difference is that if the main module changes at runtime, require.main
might still refer to the original main module in modules that were requiredbefore the change occurred. Generally it's safe to assume that the two referto the same module.
和 require.main
同样, 若是没有入口脚本,将会返回undefined
。