[Node.js] 02 - Read Eval Print Loop

视频课程:带你入门Nodejs,提及了非常多的后端知识点

  • 发布时间: 2017年10月7日
  • 课程时长:193 分钟
  • 类别:后端
  • 课时:22

 

npm Resource: 

npm模块管理器【阮一峰】

npm.com【官网】

 

 

从这里开始:Node.js 命令行程序开发教程


 

命令行交互任务

  • 读取 - 读取用户输入,解析输入了Javascript 数据结构并存储在内存中。

  • 执行 - 执行输入的数据结构

  • 打印 - 输出结果

  • 循环 - 循环操作以上步骤直到用户两次按下 ctrl-c 按钮退出。

 

加入环境变量

$ ./hello
hello world

//更为简单的执行
$ hello
hello world

执行步骤:

Step 1, 在当前目录下新建 package.json

{
"name": "hello", "bin": { "hello": "hello" } }


Step 2, run this.

$ npm link

 

命令行参数

process.argv[...] 获取参数。

#!/usr/bin/env node
console.log('hello ', process.argv[2]);

 

新建进程

child_process模块:node.js是基于单线程模型架构,这样的设计可以带来高效的CPU利用率,但是无法却利用多个核心的CPU,为了解决这个问题,node.js提供了child_process模块。

#!/usr/bin/env node
var name = process.argv[2];
var exec = require('child_process').exec;

var child = exec('echo hello ' + name, function(err, stdout, stderr) {
  if (err) throw err;
  console.log(stdout);
});

 

Shell的调用

安装 ---->

npm install --save shelljs

shelljs 模块重新包装了 child_process,调用系统命令更加方便。它需要安装后使用。

#!/usr/bin/env node
var name = process.argv[2];
var shell = require("shelljs");

shell.exec("echo hello " + name);  // 非全局模式,有点是函数模式

全局模式允许直接在脚本中写 shell 命令。

require('shelljs/global');

if (!which('git')) {
  echo('Sorry, this script requires git');
  exit(1);
}

mkdir('-p', 'out/Release');
cp('-R', 'stuff/*', 'out/Release');

cd('lib');
ls('*.js').forEach(function(file) {
  sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
  sed('-i', /.*REMOVE_THIS_LINE.*\n/, '', file);
  sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, cat('macro.js'), file);
});
cd('..');

if (exec('git commit -am "Auto-commit"').code !== 0) {
  echo('Error: Git commit failed');
  exit(1);
}

  

Shell的参数处理

安装 ----> 

$ npm install --save yargs

yargs 模块yargs 模块能够解决如何处理命令行参数

#!/usr/bin/env node
var argv = require('yargs').argv;

console.log('hello ', argv.name);

方便提取参数。

$ hello --name=tom
hello tom

$ hello --name tom
hello tom

进一步,支持多个别名(短参数,长参数)。

#!/usr/bin/env node
var argv = require('yargs')
  .alias('n', 'name')      # 指定 name 是 n 的别名
  .argv;

console.log('hello ', argv.n); 

更为奇巧的,console.log(argv._),可以获取非连词线开头的参数

$ hello A -n tom B C
hello  tom
[ 'A', 'B', 'C' ]

 

命令行参数的配置

  • demand:是否必选
  • default:默认值
  • describe:提示

更多参数处理选项

#!/usr/bin/env node
var argv = require('yargs')
  .demand(['n'])          // n参数不可省略
  .default({n: 'tom'})    // 且默认值为tom 
  .describe({n: 'your name'})
  .argv;

console.log('hello ', argv.n);

options 方法允许将所有这些配置写进一个对象,{ }内就不用再写那么多重复的"n"了。

#!/usr/bin/env node
var argv = require('yargs')
  .option('n', {
    alias : 'name',
    demand: true,
    default: 'tom',
    describe: 'your name',
    type: 'string'
  })
  .argv;

console.log('hello ', argv.n);

  

判断有没有该参数

可以用 boolean 方法指定这些参数返回布尔值。

#!/usr/bin/env node
var argv = require('yargs')
  .boolean(['n'])
  .argv;

console.log('hello ', argv.n);

有该参数,返回true;否则,返回false。

$ hello
hello  false
$ hello -n
hello  true
$ hello -n tom
hello  true

boolean 方法也可以作为属性,写入 option 对象。

#!/usr/bin/env node
var argv = require('yargs')
  .option('n', {
    boolean: true
  })
  .argv;

console.log('hello ', argv.n);

 

帮助信息

yargs 模块提供以下方法,生成帮助信息。

usage:  用法格式
example:提供例子
help:   显示帮助信息
epilog: 出现在帮助信息的结尾 

希望达到的效果:

$ hello -h

Usage: hello [options]

Options:
  -f, --name  your name [string] [required] [default: "tom"]
  -h, --help  Show help [boolean]

Examples:
  hello -n tom  say hello to Tom

copyright 2015

实现方式:

#!/usr/bin/env node
var argv = require('yargs')
  .option('f', {
    alias : 'name',
    demand: true,
    default: 'tom',
    describe: 'your name',
    type: 'string'
  })
  .usage('Usage: hello [options]')
  .example('hello -n tom', 'say hello to Tom')
  .help('h')
  .alias('h', 'help')
  .epilog('copyright 2015')
  .argv;

console.log('hello ', argv.n);

 

子命令

yargs 模块还允许通过 command 方法,设置 Git 风格的子命令。 

$ hello morning -n tom
Good Morning
hello tom

实现方式就是使用两次command(...),或者再与 shellojs 模块结合起来

#!/usr/bin/env node
require('shelljs/global');
var argv = require('yargs') .command("morning", "good morning", function (yargs) { echo("Good Morning"); }) .command("evening", "good evening", function (yargs) { echo("Good Evening"); }) .argv; console.log('hello ', argv.n);

 

子命令设置各自的参数形式:

每个子命令往往有自己的参数,这时就需要在回调函数中单独指定。回调函数中,要先用 reset 方法重置 yargs 对象。

#!/usr/bin/env node
require('shelljs/global');
var argv = require('yargs') .command("morning", "good morning", function (yargs) { echo("Good Morning");
var argv = yargs.reset() .option("m", { alias: "message", description: "provide any sentence" }) .help("h") .alias("h", "help") .argv; echo(argv.m); }) .argv;

用法如下:

$ hello morning -m "Are you hungry?"
Good Morning
Are you hungry?

 

其他事项

(1)返回值

根据 Unix 传统,程序执行成功返回 0,否则返回 1 。

if (err) {
  process.exit(1);
} else {
  process.exit(0);
}

 

(2)重定向

Unix 允许程序之间使用管道重定向数据。

$ ps aux | grep 'node'

脚本可以通过监听标准输入的data 事件,获取重定向的数据。

process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', function(data) {
  process.stdout.write(data);
});

下面是用法。

$ echo 'foo' | ./hello
hello foo

 

(3)系统信号

操作系统可以向执行中的进程发送信号,process 对象能够监听信号事件。

process.on('SIGINT', function () {
  console.log('Got a SIGINT');
  process.exit(0);
});

发送信号的方法如下。

$ kill -s SIGINT [process_id]

 

posted @ 2018-04-05 13:49  郝壹贰叁  阅读(483)  评论(0编辑  收藏  举报