NodeJS编写命令行脚本
前言
前段时间电脑键盘和触摸板都用不了了,试了下重装系统都不行,还不小心丢了博客的 markdown
源文件,只剩 github
上的 html
文件…
事隔几个月后,刚好公司项目在发版前都要修改一些参数(如版本号等),人工修改的方式存在漏改或改错的风险,便学了下 NodeJS 写了个预发布脚本(然后也一起写了个工具将 hexo 的 html 文件转为需要的 markdown 文件…)
找回 markdown 的代码放上 gist 了,不过由于不同主题的样式是不一样的,所以这份代码只适用于 next主题 产生的 html 文件,另外 about 文件结构不太一样,就单独去复制处理了。
本文主要记录如何使用 NodeJS 编写脚本。
简单写法
编写一个简单的脚本,只需要在 js 文件里声明运行环境,再赋予 js 文件可执行权限即可,如:
1 | mkdir ~/Desktop/cmd && cd ~/Desktop/cmd |
之后输入以下内容:
1 | #!/usr/bin/env node |
最后运行命令 ./hello.js
或 node hello.js
即可
如果想用更简洁的命令(如 hello
),有两种方式:
将
hello.js
的路径加入环境变量更好的做法是在当前目录使用
npm init
命令创建一个新的npm
项目,然后编辑package.json
文件,加入以下内容:1
2
3
4
5
6...
"bin": {
"hello": "./hello.js",
"hlo": "./hello.js"
}
...PS:
bin
里可以加入多个命令,如上面加多了一个hlo
命令之后将
hello
或是hlo
链接到系统变量即可:- 开发时,一般使用
npm link
将hello.js
软链接到path
变量的位置;如果想要删除,可以使用npm unlink
(或是使用which hello
或which hlo
命令找到路径再去手动删除)
1
2
3
4
5
6$ npm link
# 输出以下信息就表示软链接成功了
/usr/local/bin/hello -> /usr/local/lib/node_modules/cmd/hello.js
/usr/local/bin/hlo -> /usr/local/lib/node_modules/cmd/hello.js
/usr/local/lib/node_modules/cmd -> /Users/aevit/Desktop/cmd- 如果想要直接安装,可以使用
npm install -g
1
2
3
4
5$ npm install -g
# 这样就安装完成了
/usr/local/bin/hello -> /usr/local/lib/node_modules/cmd/hello.js
/usr/local/bin/hlo -> /usr/local/lib/node_modules/cmd/hello.js开发完成后,就可以通过
npm publish
命令将脚本发布到 npm 上了,其他人就可以通过npm install -g hello
来安装了。- 开发时,一般使用
解析参数
如果我们的命令需要处理用户输入的内容,只要用 process.argv
就可以拿到参数了,如:
1 | #!/usr/bin/env node |
运行结果如下:
1 | $ ./hello.js aevit |
以上命令,实际执行的是 node ./hello.js aevit
(这里 node 和 ./hello.js 都省略了全路径,可以去打印 process.argv
实际看一下),所以 process.argv[2]
就可以取到 aevit
这个值了。
这里推荐使用 commander 来解析参数,安装完成后就可以使用以下可读性较强的方式来定义用户输入参数(具体用法请见其 README):
1 | #!/usr/bin/env node |
执行结果如下:
1 | $ ./hello.js hello aevit -u aevit -p 111 |
输出彩色
如果你想要在终端里输出彩色的内容,使用 chalk 就可以方便地输出各种颜色了,如:
1 | #!/usr/bin/env node |
详细用法可查看其 README
询问输入
如果你想要询问式地处理用户输入,可以使用 Inquirer:
1 | #!/usr/bin/env node |
以上代码使用了两个 inquirer,第一个要求输入用户名和密码,获取结果是采用 promise then
的方式得到;第二个询问是否确定,这里使用 ES6
的 async await
语法来获取。
运行结果如下:
1 | $ ./hello.js login |
网络请求
如果你想要发起网络请求,可以使用 superagent 或 isomorphic-fetch 等第三方库。
如使用 superagent
来发起请求:
1 | request |
进度条
假设你上传数据时,需要使用进度条,可以使用 node-progress,样式如下:
1 | downloading [===== ] 39/bps 29% 3.7s |
系统命令
如果你想要执行一些系统命令,如 ls
,可以使用 child_process 新建子进程去执行,如:
1 | #!/usr/bin/env node |
总结
刚开始是想用 PHP 写脚本,但是因为项目用的是 React-Native
,所以最后还是使用 NodeJS 来写,最终发现 NodeJS 确实挺不错的…
纸上学来终觉浅,趁着这次写了两个脚本,也借着这次机会学了下正则(惭愧,这么多年都没去看正则相关的,都是能不用正则就不用,需要再去查找…)
终于把 markdown 文件弄回来了,也好久没写文章了…
以下是转 markdown 脚本的最终成果:
参考资料:
【译】使用Node.js创建命令行脚本工具
Node.js 命令行程序开发教程
2017-09-07 21:49
Aevit
深圳南山
摄影:Aevit 2015年6月 阳江闸坡十里银滩