我如何传递命令行参数?

我有一个用Node.js编写的Web服务器,我想用特定的文件夹启动。 我不知道如何访问JavaScript中的参数。 我像这样运行节点:

$ node server.js folder 

这里server.js是我的服务器代码。 Node.js的帮助说这是可能的:

 $ node -h Usage: node [options] script.js [arguments] 

我将如何访问JavaScript中的这些参数? 不知何故,我无法在网上find这些信息。

标准方法(无库)

参数存储在process.argv

以下是处理命令行参数的节点文档:

process.argv是一个包含命令行参数的数组。 第一个元素是'node',第二个元素是JavaScript文件的名字。 下一个元素将是任何额外的命令行参数。

 // print process.argv process.argv.forEach(function (val, index, array) { console.log(index + ': ' + val); }); 

这将产生:

 $ node process-2.js one two=three four 0: node 1: /Users/mjr/work/node/process-2.js 2: one 3: two=three 4: four 

为了像常规的javascript函数那样标准化参数,我在我的node.js shell脚本中这样做:

 var args = process.argv.slice(2); 

请注意,第一个参数通常是nodejs的path,第二个参数是您正在执行的脚本的位置。

最新的正确答案是它使用最小化库。 我们曾经使用节点乐观主义者,但是自那时以来已被弃用。

下面是一个如何使用它从最小化文档直接采取的例子:

 var argv = require('minimist')(process.argv.slice(2)); console.dir(argv); 

 $ node example/parse.js -a beep -b boop { _: [], a: 'beep', b: 'boop' } 

 $ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz { _: [ 'foo', 'bar', 'baz' ], x: 3, y: 4, n: 5, a: true, b: true, c: true, beep: 'boop' } 

2017基于当前stream行趋势的答案:


香草JavaScript参数parsing:

 const args = process.argv; console.log(args); 

这返回:

 $ node server.js one two=three four ['node', '/Users/dc/node/server.js', 'one', 'two=three', 'four'] 

官方文档


大多数用于参数分析的NPM包:

Minimist :用于最小参数分析。

Yargs :对于更复杂的参数parsing。

Commander.js :用于构build使用和退出的命令行应用程序,内置参数parsing。

:替代Commander.js

Vorpal.js :用于构build成熟的,交互式的命令行应用程序,内置参数parsing。

乐观主义者(节点乐观主义者)

看看乐观主义者的库 ,它比手工parsing命令行选项要好得多。

更新

乐观主义者已被弃用。 尝试乐观主义的活跃分支。

Commander.js

非常适合定义您的选项,操作和参数。 它也为你生成帮助页面。

及时

如果您喜欢回拨方式,则可以很好地从用户那里获得input。

联合提示

如果你喜欢发电机的方法,非常适合从用户那里获得input。

这里有几个很好的答案,但似乎都很复杂。 这与bash脚本如何访问参数值非常相似,并且已经像MooGoo指出的那样,已经为node.js提供了标准。 (只是为了让nodeme.js的新手能理解)

例:

 $ node yourscript.js banana monkey var program_name = process.argv[0]; //value will be "node" var script_path = process.argv[1]; //value will be "yourscript.js" var first_value = process.argv[2]; //value will be "banana" var second_value = process.argv[3]; //value will be "monkey" 

Stdio图书馆

在NodeJS中parsing命令行参数的最简单方法是使用stdio模块。 受到UNIX getopt实用程序的启发,它如下所示:

 var stdio = require('stdio'); var ops = stdio.getopt({ 'check': {key: 'c', args: 2, description: 'What this option means'}, 'map': {key: 'm', description: 'Another description'}, 'kaka': {args: 1, mandatory: true}, 'ooo': {key: 'o'} }); 

如果你用这个命令运行前面的代码:

 node <your_script.js> -c 23 45 --map -k 23 file1 file2 

那么ops对象将如下所示:

 { check: [ '23', '45' ], args: [ 'file1', 'file2' ], map: true, kaka: '23' } 

所以你可以使用它,只要你想。 例如:

 if (ops.kaka && ops.check) { console.log(ops.kaka + ops.check[0]); } 

也支持分组选项,因此可以使用-om而不是-o -m

而且, stdio可以自动生成帮助/使用输出。 如果你调用ops.printHelp()你会得到以下结果:

 USAGE: node something.js [--check <ARG1> <ARG2>] [--kaka] [--ooo] [--map] -c, --check <ARG1> <ARG2> What this option means (mandatory) -k, --kaka (mandatory) --map Another description -o, --ooo 

如果没有给出强制选项(在错误消息前面)或错误指定(例如,如果为选项指定单个参数,并且需要2),则会显示前面的消息。

您可以使用NPM安装stdio模块:

 npm install stdio 

如果您的脚本被称为myScript.js,并且想要传递名字“Sean Worthington”的名字,如下所示:

 node myScript.js Sean Worthington 

然后在脚本中写下:

 var firstName = process.argv[2]; // Will be set to 'Sean' var lastName = process.argv[3]; // Will be set to 'Worthington' 

命令行参数值得一看!

您可以使用主要标记标准(getopt,getopt_long等)设置选项。 这些命令都是相同的,设置相同的值:

 $ example --verbose --timeout=1000 --src one.js --src two.js $ example --verbose --timeout 1000 --src one.js two.js $ example -vt 1000 --src one.js two.js $ example -vt 1000 one.js two.js 

要访问这些值,请首先描述您的应用程序接受的选项(请参阅选项定义)。

 const commandLineArgs = require('command-line-args') const optionDefinitions = [ { name: 'verbose', alias: 'v', type: Boolean }, { name: 'src', type: String, multiple: true, defaultOption: true }, { name: 'timeout', alias: 't', type: Number } ] 

type属性是一个setter函数(所提供的值是通过这个函数传递的),让你完全控制接收到的值。

接下来,使用commandLineArgsparsing选项:

 const options = commandLineArgs(optionDefinitions) 

options现在看起来像这样:

 { files: [ 'one.js', 'two.js' ], verbose: true, timeout: 1000 } 

处理大量的选项时,将它们分组是很有意义的。

使用指南可以使用命令行使用来生成,例如:

用法

符号规则

用于设置命令行选项的符号规则。

  • 论据顺序是微不足道的。 无论你在arg列表的开始还是结尾设置--example都没有什么区别。
  • 一个Booleantypes的选项不需要提供一个值。 设置--flag-f会将该选项的值设置为true 。 这是具有特殊行为的唯一types。
  • 三种设置期权价值的方法
    • --option value
    • --option=value
    • -o value
  • 两种方式来设置值列表(在多个选项上)
    • --list one two three
    • --list one --list two --list three
  • 短的选项(别名)可以分组设置。 以下是等同的:
    • -a -b -c
    • -abc

不明确的值

想象一下,我们使用“grep-tool”来searchstring'-f'

 $ grep-tool --search -f 

我们在这里有一个问题:命令行参数会假定我们正在设置两个选项( --search-f )。 实际上,我们通过一个选项( --search )和一个值( -f )。 在这种情况下,通过使用--option=value notation来避免模棱两可的情况:

 $ grep-tool --search=-f 

部分parsing

默认情况下,如果用户设置一个没有有效定义的选项,则抛出UNKNOWN_OPTIONexception。 但是,在某些情况下,您可能只对希望将其余部分传递给另一个库的选项部分感兴趣。 在这里看一个例子,显示这可能是必要的。

要启用部分parsing,请在方法选项中设置partial: true

 const optionDefinitions = [ { name: 'value', type: Number } ] const options = commandLineArgs(optionDefinitions, { partial: true }) 

现在,是否应该在命令行传递未知的参数:

 $ example --milk --value 2 --bread cheese 

它们将在commandLineArgs输出的_unknown属性中返回,不会引发任何exception:

 { value: 2, _unknown: [ '--milk', '--bread', 'cheese'] } 

有一个应用程序。 那么,模块。 好吧,不止一个,大概有几百个。

Yargs是有趣的之一,它的文档很酷阅读。

下面是一个来自github / npm页面的例子:

 #!/usr/bin/env node var argv = require('yargs').argv; console.log('(%d,%d)', argv.x, argv.y); console.log(argv._); 

输出在这里(它读取破折号等选项,短期和长期,数字等)。

 $ ./nonopt.js -x 6.82 -y 3.35 rum (6.82,3.35) [ 'rum' ] $ ./nonopt.js "me hearties" -x 0.54 yo -y 1.12 ho (0.54,1.12) [ 'me hearties', 'yo', 'ho' ] 

这可能是一个好主意,用nconf https://github.com/flatiron/nconf来集中pipe理你的configuration

它可以帮助你处理configuration文件,环境variables,命令行参数。

传递,parsing参数是一个简单的过程。 Node为您提供了process.argv属性,它是一个string数组,它是Node被调用时使用的参数。 数组的第一个条目是Node可执行文件,第二个条目是脚本的名称。

如果你用下面的参数运行脚本

 $ node args.js arg1 arg2 

文件:args.js

 console.log(process.argv) 

你会得到像arrays

  ['node','args.js','arg1','arg2'] 

你可以parsing所有参数并检查它们是否存在。

file:parse-cli-arguments.js:

 module.exports = function(requiredArguments){ var arguments = {}; for (var index = 0; index < process.argv.length; index++) { var re = new RegExp('--([A-Za-z0-9_]+)=([A/-Za-z0-9_]+)'), matches = re.exec(process.argv[index]); if(matches !== null) { arguments[matches[1]] = matches[2]; } } for (var index = 0; index < requiredArguments.length; index++) { if (arguments[requiredArguments[index]] === undefined) { throw(requiredArguments[index] + ' not defined. Please add the argument with --' + requiredArguments[index]); } } return arguments; } 

比只是做:

 var arguments = require('./parse-cli-arguments')(['foo', 'bar', 'xpto']); 
 npm install ps-grab 

如果你想运行这样的东西:

 node greeting.js --user Abdennour --website http://abdennoor.com 

 var grab=require('ps-grab'); grab('--username') // return 'Abdennour' grab('--action') // return 'http://abdennoor.com' 

或者类似的东西:

 node vbox.js -OS redhat -VM template-12332 ; 

 var grab=require('ps-grab'); grab('-OS') // return 'redhat' grab('-VM') // return 'template-12332' 

您可以使用system.args到达命令行参数。 我使用下面的解决scheme来parsing参数到一个对象,所以我可以得到哪一个我想要的名称。

 var system = require('system'); var args = {}; system.args.map(function(x){return x.split("=")}) .map(function(y){args[y[0]]=y[1]}); 

现在你不需要知道参数的索引。 使用它像args.whatever

注意:你应该使用像file.js x=1 y=2这样的命名参数来使用这个解决scheme。

没有图书馆

如果你想在香草JS / ES6中做到这一点,你可以使用下面的解决scheme

仅在NodeJS> 6中工作

 const args = process.argv .slice(2) .map((val, i)=>{ let object = {}; let [regexForProp, regexForVal] = (() => [new RegExp('^(.+?)='), new RegExp('\=(.*)')] )(); let [prop, value] = (() => [regexForProp.exec(val), regexForVal.exec(val)] )(); if(!prop){ object[val] = true; return object; } else { object[prop[1]] = value[1] ; return object } }) .reduce((obj, item) => { let prop = Object.keys(item)[0]; obj[prop] = item[prop]; return obj; }, {}); 

而这个命令

 node index.js host=http://google.com port=8080 production 

会产生以下结果

 console.log(args);//{ host:'http://google.com',port:'8080',production:true } console.log(args.host);//http://google.com console.log(args.port);//8080 console.log(args.production);//true 

ps请更正地图中的代码,并减lessfunction,如果你find更优雅的解决scheme,谢谢;)

没有pipe理库:使用Array.prototype.reduce()

 const args = process.argv.slice(2).reduce((acc, arg) => { let [k, v = true] = arg.split('=') acc[k] = v return acc }, {}) 

对于这个命令node index.js count=2 print debug=false msg=hi

 console.log(args) // { count: '2', print: true, debug: 'false', msg: 'hi' } 

也,

我们可以改变

  let [k, v = true] = arg.split('=') acc[k] = v 

由(更长)

  let [k, v] = arg.split('=') acc[k] = v === undefined ? true : /true|false/.test(v) ? v === 'true' : /[\d|\.]+/.test(v) ? Number(v) : v 

自动分析布尔值和数字

 console.log(args) // { count: 2, print: true, debug: false, msg: 'hi' } 

一个简单的片段,如果有需要的话:

 var fs = require('fs'), objMod = {}; process.argv.slice(2).map(function(y, i) { y = y.split('='); if (y[0] && y[1]) objMod[y[0]] = y[1]; else console.log('Error in argument number ' + (i+1)); });