Node可以很方便地进行命令行程序的开发,我们所接触到的sass、less、npm等程序,都是命令行程序。
一、可执行脚本
自从有了Node后,我们就可以使用JavaScript来编写可执行脚本了。最简单的可执行脚本hello
如下:
#!/usr/bin/env node
console.log('Hello world!')
修改脚本权限
$ chmod 0755 path/to/hello
执行脚本:
$ ./hello
# 输出 'Hello world!'
我们发现,这里是直接使用./hello
的方式执行脚本,而不是node hello.js
的方式,这是因为我们使用了#!/usr/bin/env node
的缘故。据说程序员都是偷懒的,那么我们觉得./hello
也太繁琐了,有没有更简单点的方式呢?
我们可以:
1)将hello的路径加入环境变量PATH
2)使用npm link
命令
再执行
$ hello
即可
二、命令行参数的原始写法
命令行参数可以用process.argv
获取,如:
#!/usr/bin/env node
console.log('Hello', process.argv[2]);
执行:
$ ./hello RuphiLau
# 输出:Hello RuphiLau
上述例子执行的实际上是:
node hello.js RuphiLau
而process.argv
将被填充如:
[
'/usr/local/Cellar/node/7.7.2/bin/node',
'/Users/Ame/Desktop/Node/hello',
'RuphiLau'
]
三、新建进程
脚本可以使用child_process
模块来新建子进程从而执行Unix系统命令,如:
let name = process.argv[2];
const exec = require('child_process').exec;
let child = exec('echo hello ' + name, (err, stdout, stderr) => {
if (err) throw err;
console.log(stdout);
});
执行:
$ ./hello RuphiLau
# 输出:Hello RuphiLau
四、yargs模块
yargs
模块可以被方便地用来处理命令行参数,安装方法如:
npm install --save yargs
1、读取参数
对于下列形式的命令行:
$ ./hello --name=RuphiLau
$ ./hello --name RuphiLau
可以方便地进行读取,其方式为:
1)载入yargs
模块中的argv
:const argv = require('yargs').argv
2)使用argv.name
读取
2、一个字母的短参
对于一个字母的短参数,如:
$ ./hello -n RuphiLau
可以用一个字母作为argv
对象的键名来指定,如:argv.n
3、长短参结合
如果既希望可以用短参数,又可以用长参数,如:
$ ./hello --name RuphiLau
$ ./hello --name=RuphiLau
$ ./hello -n RuphiLau
那么可以使用alias
方法,如:
#!/usr/bin/env node
const argv = require('yargs')
.alias('n', 'name')
.argv;
获取的时候则统一使用argv.n
获取就可以了
4、非-
开头的参数
可以使用argv._
获取非-
开头的属性,如:
$ ./hello A -n tom B C
则argv._
的值为:
['A', 'B', 'C']
五、命令行参数的配置
yargs
可以使用3个方法来配置命令行参数,如:
demand
参数是否必选default
指定默认值describe
指定提示
例子如:
#!/usr/bin/env node
let argv = require('yargs')
.demand(['n'])
.default({
n: 'RuphiLau'
})
.describe({
n: 'Your name'
})
.argv;
代码指定参数n
不可忽略,并且默认值为RuphiLau
除了这种方式外,我们可以使用option()
方法来将所有的这些配置写进一个对象里,如:
#!/usr/bin/env node
let argv = require('yargs')
.option('n', {
alias: 'name',
demand: true,
default: 'RuphiLau',
describe: 'Your name',
type: 'string'
})
.argv;
有些情况下,有些参数不需要值,它们起的只是一个开关的作用,这种情况下,可以使用boolean()
方法指定参数返回布尔值,比如许多工具里可以用-w
选项来配置是否观测文件,那么就可以如下这么使用:
let argv = require('yargs')
.boolean(['n'])
.argv;
这种情况下,只要有传开关参数,无论什么情况下都会返回true
,只有不传的情况下才会返回false
,而这个属性,也可以传入option()
方法里(如option({ boolean: true })
六、帮助信息
yargs
模块提供了一些有用的方法,来帮助我们生成帮助信息,如:
usage
用法格式example
提供例子help
显示帮助信息epilog
出现在帮助信息的结尾
例子如下:
#!/usr/bin/env node
let argv = require('yargs')
.option('f', {
alias: 'name',
demand: true,
default: 'RuphiLau',
describe: 'Your name',
type: 'string'
})
.usage('Usage: hello [options]')
.example('hello -n RuphiLau', 'say hello to RuphiLau')
.help('h')
.alias('h', 'help')
.epilog('Copyright 2015')
.argv;
执行$ ./node -h
得到:
选项:
-f, --name Your name [字符串] [必需] [默认值: "RuphiLau"]
-h, --help 显示帮助信息 [布尔]
示例:
hello -n RuphiLau say hello to RuphiLau
Copyright 2015
七、子命令
对于形如git commit -m
风格的命令,yargs
也是提供了支持的,主要是通过command()
方法,如下:
let argv = require('yargs')
.command('commit', 'commit your code', function(yargs) {
let argv = yargs.reset()
.option('m', {
alias: 'message',
description: 'provide any sentence'
})
.help('h')
.argv;
console.log(argv.m);
})
.argv;