我如何传递命令行参数?
我有一个用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
都没有什么区别。 - 一个
Boolean
types的选项不需要提供一个值。 设置--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_OPTION
exception。 但是,在某些情况下,您可能只对希望将其余部分传递给另一个库的选项部分感兴趣。 在这里看一个例子,显示这可能是必要的。
要启用部分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)); });