07-进程
20.6 进程
每个正在运行的Node程序都能访问一个名为process的变量,通过这个变量能够获取程序的相关信息,同时控制程序的执行。比如,如果应用程序在运行时出现了严重的错误,那么继续运行(通常被称为重大错误—fatal error)显然不明智,也没有意义,这时就能用proces.exit立刻中止程序。也可以提供一个用数字表示的错误码,在脚本中通过这个数字就可以知道程序是否正常退出。按照惯例,0代表“没有错误”,而其他数字则对应不同的代码错误。下面来看一个例子,有一个会处理data子目录中.txt文件的脚本:如果没有文件可处理,那就什么都不做,程序会立即退出,但这并不是错误。另一方面,如果data子目录不存在,就意味着出现了一个很严重的问题,程序应该立即报错并退出。所以代码可能就是这个样子的:
const fs = require('fs');
fs.readdir('data', function(err, files) {
if(err) {
console.error("Fatal error: couldn't read data directory.");
process.exit(1);
}
const txtFiles = files.filter(f => /\.txt$/i.test(f));
if(txtFiles.length === 0) {
console.log("No .txt files to process.");
process.exit(0);
}
// 处理后缀为.txt的文件
});
使用process对象还可以访问包含了传入到程序中的命令行参数的数组。在执行Node应用程序时,可以选择传入一些命令行参数。比如,可以写一段程序,它将从命令行接收多个文件名作为参数,然后打印出每个文件有多少行。可以这样来执行它:
$ node linecount.js file1.txt file2.txt file3.txt
命令行参数会保存在一个叫作process.argv的数组[2]中。在开始计算行数前,可以先打印出process.argv,这样就能明确地看到传入的参数了:
console.log(process.argv);
连同le1.txt、le2.txt、le3.txt的输出,会发现在数组开头有一些额外的元素:
[ 'node',
'/home/jdoe/linecount.js',
'file1.txt',
'file2.txt',
'file3.txt' ]
其中,第一个元素是解释器,或者解释源文件的程序(在本例中是node)。第二个元素是所执行脚本的完整路径,剩下的内容则是传入程序中的参数。因为不需要这些额外信息,所以可以在执行程序前,用Array.slice去掉这些多余的信息:
const fs = require('fs');
const filenames = process.argv.slice(2);
let counts = filenames.map(f => {
try {
const data = fs.readFileSync(f, { encoding: 'utf8' });
return `${f}: ${data.split('\n').length}`;
} catch(err) {
return `${f}: couldn't read file`;
}
});
console.log(counts.join('\n'));
process 还可以通过 process.env 访问环境变量。环境变量是以系统变量命名的变量,它们主要被用在命令行编程中。在大多数Unix系统中,可以简单地通过export VAR_NAME=some value来设置环境变量(环境变量的传统写法都是使用大写)。在Windows上,可以用VAR_NAME=some value。环境变量通常用来配置一些应用程序的行为(这样就不用在每次执行程序的时候从命令行传入了)。
例如,大家可能想用环境变量来控制是否打印debug的log,还是“只让程序安静的运行”。通过一个叫作DEBUG的环境变量就可以控制这个行为,当DEBUG设为1的时候,就表示希望debug(其他值表示不用debug):
const debug = process.env.DEBUG === "1" ?
console.log :
function() {};
debug("Visible only if environment variable DEBUG is set!");
在这个例子中,创建一个名为debug的函数,如果将DEBUG设为1,那这个函数就是console.log的别名,如果DEBUG是其他值,那这个函数就等价于一个空函数_:什么也没做(如果debug是undefined,就在调用到它的时候报错!)。
在上一章节中,我们提到默认的是当前工作目录,就是执行程序的目录(而非程序所在的目录)。process.cwd可以说明当前工作目录是什么,而process.chdir则可以修改它。比如,如果想要打印程序开始运行时的目录,然后将当前工作目录切换成程序所在目录,可以这样做:
console.log(`Current directory: ${process.cwd()}`);
process.chdir(__dirname);
console.log(`New current directory: ${process.cwd()}`);