process.argv與命令列工具

Cris_冷崢子發表於2018-03-01

process.argv

process是node中的一個模組,通過訪問process.argv我們能輕鬆愉快的接收通過命令執行node程式時候所傳入的引數。

[info] argv翻譯成中文意思是:命令列變元陣列。

這是什麼意思呢?我們都在命令列視窗中使用過npm命令來進行包的下載,在使用npm命令的時候我們還能進行一些傳參,像要下載的包的名字啊,是開發依賴還是生產依賴啊。

這些所傳的引數+node.exe絕對路徑+node所執行檔案的絕對路徑所組成的陣列 = process.argv。它不止包含所傳的引數還包含另外兩個東東作為陣列成員,故稱之為變元陣列。

示例1

// 檔案p1.js中console.log(process.argv);
>
>
>
命令列中輸入node p1.js --a -b c<
<
<
輸出E:\w>
node p1.js --a -b c[ 'C:\\Program Files\\nodejs\\node.exe', 'E:\\w\\p1.js', '--a', '-b', 'c' ] 複製程式碼

批處理檔案

批處理檔案,顧名思義,它能達到通過只執行一個檔案從而執行多條node命令的效果,它能極大的簡化我們在命令列中的輸入,我們只需要輸入批處理檔案的名字,甚至不需要輸 node這個字首。批處理檔案在不同的作業系統下是不一樣的,主要分為:

  • window下的批處理檔案
  • 類linux下的批處理檔案

windows中的批處理檔案

windows中的批處理檔案字尾名為.bat

//hello.bat檔案中node p.js -a hello -b world>
>
>
命令列中hello //為xx.bat檔案去掉字尾的檔名<
<
<
輸出[ 'C:\\Program Files\\nodejs\\node.exe', 'E:\\w\\p1.js', '-a', 'hello', '-b', 'world' ]複製程式碼

佔位符

在上面的栗子中有一個問題,我們所傳入的引數是固定的,要想它不固定,需要在.bat檔案中使用佔位符取代原本固定的引數,再在執行批處理檔案時通過傳參進行對映。

//hello.bat檔案中node p.js %1 %2 %3 %4>
>
>
命令列中輸入hello -a hello -b world //為xx.bat檔案去掉字尾的檔名<
<
<
輸出[ 'C:\\Program Files\\nodejs\\node.exe', 'E:\\w\\p1.js', '-a', 'hello', '-b', 'world' ]複製程式碼

[warning] 注意:

  • 此時%後面的數字代表了%x這個佔位符代表是第幾個傳入的引數
  • %x是從%1開始的而不是%0

上面雖然使傳參所傳入的引數值不再固定化了,但個數仍然是固定的,so我們推薦下面這種類linux的批處理檔案。

類linx中的批處理檔案

此時,我們不再需要.bat字尾名,我們的批處理檔名直接就是xxx(不再需要字尾)。

給檔案新增可執行許可權

假若我們要執行的檔名為hello,要執行這個批處理檔案,我們需要先給它新增可執行許可權

$ chmod +x hello複製程式碼

告訴命令列讓誰來執行這個檔案裡的內容

接著,在這個檔案中新增一句話,意思是讓node來執行這個命令

#! /usr/bin/env node複製程式碼

‘./’執行檔案

最後,如何執行這個檔案呢,只需要訪問它即可

>
>
>
輸入$ ./hello --a -b c<
<
<
輸出[ 'C:\\Program Files\\nodejs\\node.exe', 'E:\\w\\hello', '--a', '-b', 'c' ]複製程式碼

[danger] 注意: 此時./是必須的

npm link

如果我們想在輸入命令時不需要輸入前面的’./’,我們就需要用到npm link了。首先,在package.json下,新增這麼一段

"bin":{ 
"hello":"hello" //前者為我們輸入的命令,後者為要執行的檔案的路徑(包括檔名)
}複製程式碼

接著在package.json所處目錄下的命令列中輸入

npm link複製程式碼

這樣我們就無需在輸入命令時候還要加上./字首。

[important]注意:

  1. 這是因為npm link後,命令列中的命令指向了npm目錄bat檔案(npm-link後會自動在npm目錄下生成,其作用是將package.json中我們所配置的那個可執行檔案掛到這個.bat下),而 bat檔案又指向了當前目錄 (package.json所處目錄)的hello檔案(路徑)。

  2. npm link 必須配合 #! /usr/bin/env node,否則windows會報指令碼執行錯誤

yargs

yargs能幫助我們在被執行的檔案裡所接受的引數進行包裝處理。yargs.argv就是包裝後的process.argv,除此之外我們還能通過yargs.options對這個包裝物件再進行進一步的訂製。

[important] 注意:和process.argv很大的不同是它返回的是一個物件而不是陣列,以連詞線 ---開頭的引數會作為物件中的一個key值,而它後面的非連詞線開頭的引數會作為key的值,如果後面沒有非連詞線開頭的引數則會返回true

//hello檔案中#! /usr/bin/env nodelet yargs = require('yargs');
let argv = yargs.argv;
//.argv是必須的console.log(argv);
>
>
>
命令列中輸入$ ./hello --a 1 -b 2 c<
<
<
輸出{
_: [ 'c' ], help: false, version: false, a: 1, b: 2, '$0': 'hello',
}console.log(argv.a);
<
<
<
輸出1複製程式碼

下劃線屬性

我們可以通過訪問argv._來獲取非連詞線開頭的引數

>
>
>
命令列中輸入$ ./hello d --a 1 -b 2 c<
<
<
輸出[ 'd', 'c' ]複製程式碼

命令列引數的配置

多個不同引數的配置通過.option隔開

#! /usr/bin/env nodelet yargs = require('yargs');
// let argv = yargs.argv;
let argv = yargs.options('a',{
alias:'ant' ,demand:true ,default:'super' ,describe:'一隻灰常大的螞蟻' ,boolean:false ,type:'string'
}).options('b',{
alias:'BB' ,describe:'woshi bb' ,boolean:false
}).argv;
console.log(argv._);
console.log(argv);
>
>
>
命令列中輸入$ ./p1.js -a valueA -b valueB -c<
<
<
輸出[]{
_: [], help: false, version: false, a: 'valueA', ant: 'valueA', b: 'valueB', BB: 'valueB', c: true, '$0': 'p1.js'
}複製程式碼

配置項說明:

  • alias:別名,當傳入a時也會同時生成ant
  • demand:該引數是否必須
  • default:預設值
  • describe:引數描述
  • boolean:設定為true時,若該引數沒有傳入則會將該引數的值設定為false
    process.argv與命令列工具
  • type:限制傳入引數的型別

配置幫助資訊

首先yargs已經預設為我們提供了--help引數來顯示幫助資訊,我們同樣的,可以給這個–help引數配置個別名來簡化

let argv = yargs.此處省略一萬字.help('h').argv>
>
>
命令列中輸入$ ./p1.js --h<
<
<
輸出選項: --version 顯示版本號 [布林] -a, --ant 一隻灰常大的螞蟻 [字串] [必需] [預設值: "super"] -b, --BB woshi bb [布林] -h 顯示幫助資訊 [布林]複製程式碼

配置其它的幫助提示

  • usage:用法格式
  • example:一個詳細的使用栗子
  • epilog:結尾處的顯示,常用來顯示命令工具的版本行
// hello檔案中....help('h').usage('hello -[option] value').example('我,栗子,讓你明白!').epilog('copyright 2018-').argv;
>
>
>
$ ./hello -h<
<
<
hello -[option] value選項: --version 顯示版本號 [布林] -a, --ant 一隻灰常大的螞蟻 [字串] [必需] [預設值: "super"] -b, --BB woshi bb [布林] -h 顯示幫助資訊 [布林]示例: 我,栗子,讓你明白!copyright 2018-複製程式碼

yargs實現思路

let args = process.argv;
let argv = {
};
for(let i=2;
i<
args.length;
++i){
let cur = args[i];
if(/^(--)/.test(cur)){
argv[cur.slice(2)] = args[++i];

}
}複製程式碼

來源:https://juejin.im/post/5a976e87f265da4e8c453eec

相關文章