关于javascript:如何将命令行参数传递给node.js程序?

How do I pass command line arguments to a Node.js program?

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

1
$ node server.js folder

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

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

我如何在javascript中访问这些参数?不知怎么的,我在网上找不到这些信息。


标准方法(无库)

参数存储在process.argv中。

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

process.argv is an array containing the command line arguments. The first element will be 'node', the second element will be the name of the JavaScript file. The next elements will be any additional command line arguments.

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

这将产生:

1
2
3
4
5
6
$ 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脚本中这样做:

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

注意,第一个arg通常是指向nodejs的路径,第二个arg是正在执行的脚本的位置。


最新的正确答案是使用最小化库。我们曾经使用节点乐观主义者,但后来被弃用了。

下面是一个如何使用它的示例,它直接取自最小化文档:

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

-

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

-

1
2
3
4
5
6
7
8
9
$ 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' }


2018年答案基于当前的野外趋势:普通的javascript参数解析:

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

这种回报:

1
2
$ node server.js one two=three four
['node', '/home/server.js', 'one', 'two=three', 'four']

官方文件

用于参数分析的最常用NPM包:

最小化:用于最小参数解析。

commander.js:最常用的参数解析模块。

喵:比JS指挥官更轻的选择

雅格斯:更复杂的论点分析(重)。

vorpal.js:成熟/交互式命令行应用程序,支持参数解析。


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

查看optimist库,它比手工解析命令行选项要好得多。

更新

乐观主义者被弃用了。试试雅格斯,这是乐观主义者的一个积极分支。


这里有几个很好的答案,但似乎都很复杂。这与bash脚本访问参数值的方式非常相似,正如moogo指出的那样,它已经为node.js提供了标准。(只是为了让不熟悉node.js的人理解)

例子:

1
2
3
4
5
6
$ 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"

指挥官JS

对于定义选项、动作和论点非常有用。它还为您生成帮助页面。

及时

如果您喜欢回调方法,对于从用户那里获取输入非常有用。

共同提示

如果您喜欢生成器的方法,对于从用户那里获得输入非常有用。


STDIO图书馆

解析nodejs中命令行参数的最简单方法是使用stdio模块。受unix getopt实用程序的启发,它的功能非常简单,如下所示:

1
2
3
4
5
6
7
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'}
});

如果使用此命令运行以前的代码:

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

ops对象如下:

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

所以你可以随心所欲地使用它。例如:

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

还支持分组选项,因此您可以编写-om,而不是-o -m

此外,stdio可以自动生成帮助/使用输出。如果你打电话给ops.printHelp(),你会得到以下信息:

1
2
3
4
5
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模块:

1
npm install stdio


如果您的脚本名为myscript.js,并且您希望传递名和姓"sean worthington",参数如下:

1
node myScript.js Sean Worthington

然后在脚本中编写:

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


命令行args值得一看!

您可以使用主要符号标准设置选项(了解更多信息)。这些命令都是等效的,设置相同的值:

1
2
3
4
$ 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

要访问这些值,首先创建一个选项定义列表,描述应用程序接受的选项。type属性是一个setter函数(提供的值将通过此传递),使您可以完全控制接收到的值。

1
2
3
4
5
const optionDefinitions = [
  { name: 'verbose', alias: 'v', type: Boolean },
  { name: 'src', type: String, multiple: true, defaultOption: true },
  { name: 'timeout', alias: 't', type: Number }
]

接下来,使用commandLineargs()分析选项:

1
2
const commandLineArgs = require('command-line-args')
const options = commandLineArgs(optionDefinitions)

options现在看起来是这样的:

1
2
3
4
5
6
7
8
{
  src: [
    'one.js',
    'two.js'
  ],
  verbose: true,
  timeout: 1000
}

高级用法

除了上述典型用法之外,您还可以配置命令行参数以接受更高级的语法形式。

基于命令的语法(Git样式),格式为:

1
$ executable <command> [options]

例如。

1
$ git commit --squash -m"This is my commit message"

命令和子命令语法(Docker样式),格式为:

1
$ executable <command> [options] <sub-command> [options]

例如。

1
$ docker run --detached --image centos bash -c yum install -y httpd

使用指南生成

可以使用命令行用法生成使用指南(通常在设置--help时打印)。请参阅下面的示例,并阅读文档了解如何创建它们。

典型的使用指南示例。

usage

Polymer CLI使用指南是一个很好的实际示例。

usage

进一步阅读

还有很多东西要学习,请参阅wiki获取示例和文档。


有一个应用程序。嗯,模块。嗯,不止一个,可能是几百个。

雅格斯是其中一个有趣的,它的文件是很酷的阅读。

以下是github/npm页面的示例:

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

输出在这里(它用短划线等读取选项,短和长,数字等)。

1
2
3
4
5
6
$ ./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' ]

没有标记格式化为简单对象的libs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function getArgs () {
  const args = {}
  process.argv
    .slice(2, process.argv.length)
    .forEach( arg => {
      // long arg
      if (arg.slice(0,2) === '--') {
        const longArg = arg.split('=')
        args[longArg[0].slice(2,longArg[0].length)] = longArg[1]
      }
     // flags
      else if (arg[0] === '-') {
        const flags = arg.slice(1,arg.length).split('')
        flags.forEach(flag => {
          args[flag] = true
        })
      }
    })
  return args
}
const args = getArgs()
console.log(args)

实例简单的

输入

1
node test.js -D --name=Hello

输出

1
{ D: true, name: 'Hello' }

真实世界

输入

1
node config/build.js -lHRs --ip=$HOST --port=$PORT --env=dev

输出

1
2
3
4
5
6
7
{ l: true,
  H: true,
  R: true,
  s: true,
  ip: '127.0.0.1',
  port: '8080',
  env: 'dev' }

以下是我的命名参数的0-dep解决方案:

1
2
3
4
5
6
7
8
9
10
const args = process.argv
    .slice(2)
    .map(arg => arg.split('='))
    .reduce((args, [value, key]) => {
        args[value] = key;
        return args;
    }, {});

console.log(args.foo)
console.log(args.fizz)

例子:

1
2
3
$ node test.js foo=bar fizz=buzz
bar
buzz

注:当参数包含=时,这自然会失败。这只适用于非常简单的用法。


使用ncof https://github.com/flatiron/ncof之类的工具集中管理您的配置可能是个好主意。

它帮助您处理配置文件、环境变量和命令行参数。


Whithhout库:使用array.prototype.reduce()。

1
2
3
4
5
6
7
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

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

也,

我们可以改变

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

比(长得多)

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

自动分析布尔值&数字

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


传递、解析参数是一个简单的过程。node为您提供process.argv属性,该属性是字符串数组,是在调用node时使用的参数。数组的第一个条目是节点可执行文件,第二个条目是脚本的名称。

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

1
$ node args.js arg1 arg2

文件:ARS.JS

1
console.log(process.argv)

你会得到类似阵列的

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

您可以使用system.args访问命令行参数。我使用下面的解决方案将参数解析成一个对象,这样我就可以按名称得到我想要的参数。

1
2
3
4
5
var system = require('system');

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

现在您不需要知道参数的索引。像使用args.whatever一样使用

Note: you should use named arguments like file.js x=1 y=2 to use
this solution.


1
npm install ps-grab

如果要运行类似的程序:

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

——

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

或者类似的:

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

——

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


您可以解析所有参数并检查它们是否存在。

文件:parse-cli-arguments.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;
}

不仅仅是:

1
var arguments = require('./parse-cli-arguments')(['foo', 'bar', 'xpto']);


JS

1
2
3
for(var i=0;i<process.argv.length;i++){
  console.log(process.argv[i]);
}

终端:

1
nodemon app.js"arg1""arg2""arg3"

结果:

1
2
3
4
5
6
7
8
9
0 'C:\\Program Files\
odejs\
ode.exe'

1 'C:\\Users\
ouman\\Desktop\
ode\\camer nodejs\\proj.js'

2 'arg1' your first argument you passed.
3 'arg2' your second argument you passed.
4 'arg3' your third argument you passed.

解释:

0:机器中node.exe的目录(c:program filesodejsode.exe')

1:项目文件的目录。(J.J.JS)

2:节点的第一个参数(arg1)

3:您对node(arg2)的第二个参数

4:您对node(arg3)的第三个参数

你的实际论点开始于argv数组的2nd索引,即process.argv[2]


没有库

如果要在普通JS/ES6中执行此操作,可以使用以下解决方案

仅在nodejs>6时工作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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;
  }, {});

还有这个命令

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

将产生以下结果

1
2
3
4
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

P.S.请更正地图中的代码并减少功能如果您找到更优雅的解决方案,谢谢;)


在node.js中检索参数的最简单方法是通过process.argv数组。这是一个全局对象,您可以在不导入任何其他库的情况下使用它。您只需将参数传递给node.js应用程序,就像前面所示,这些参数可以通过process.argv数组在应用程序中访问。

process.argv数组的第一个元素始终是指向节点可执行文件的文件系统路径。第二个元素是正在执行的javascript文件的名称。第三个元素是用户实际传递的第一个参数。

1
2
3
4
5
'use strict';

for (let j = 0; j < process.argv.length; j++) {  
    console.log(j + ' -> ' + (process.argv[j]));
}

这个脚本所做的全部工作就是循环访问process.argv数组,并打印索引以及存储在这些索引中的元素。如果您对接收到的参数和顺序有疑问,那么它对于调试非常有用。

您还可以使用诸如yargs之类的库来处理commnadline参数。


虽然上面的答案是完美的,而且有人已经建议了码,使用包是非常容易的。这是一个很好的包,它使向命令行传递参数变得非常容易。

1
2
3
4
npm i yargs
const yargs = require("yargs");
const argv = yargs.argv;
console.log(argv);

更多信息请访问https://yargs.js.org/。


传递参数很容易,接收参数只是读取过程的一个问题。argv数组节点基本上可以从任何地方访问。但您肯定希望将它们作为键/值对来读取,所以您需要一个片段来编写脚本来解释它。

Joseph Merdrignac用reduce发布了一个漂亮的版本,但是它使用的是key=value语法,而不是-k value--key value。我把第二个标准改写得更难看、更长,我会把它作为答案贴出来,因为它不适合做评论。但这确实完成了任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
   const args = process.argv.slice(2).reduce((acc,arg,cur,arr)=>{
     if(arg.match(/^--/)){
       acc[arg.substring(2)] = true
       acc['_lastkey'] = arg.substring(2)
     } else
     if(arg.match(/^-[^-]/)){
       for(key of arg.substring(1).split('')){
         acc[key] = true
         acc['_lastkey'] = key
       }
     } else
       if(acc['_lastkey']){
         acc[acc['_lastkey']] = arg
         delete acc['_lastkey']
       } else
         acc[arg] = true
     if(cur==arr.length-1)
       delete acc['_lastkey']
     return acc
   },{})

使用此代码,命令node script.js alpha beta -charlie delta --echo foxtrot将提供以下对象

1
2
3
4
5
6
7
8
9
10
11
12
args = {
"alpha":true,
"beta":true,
"c":true,
"h":true,
"a":true,
"r":true
"l":true,
"i":true,
"e":"delta",
"echo":"foxtrot"
}


如节点文档所述process.argv属性返回一个数组,该数组包含启动node.js进程时传递的命令行参数。

例如,假设process-args.js的脚本如下:

1
2
3
4
// print process.argv
process.argv.forEach((val, index) => {
   console.log(`${index}: ${val}`);
});

以如下方式启动node.js进程:

1
 $ node process-args.js one two=three four

将生成输出:

1
2
3
4
5
0: /usr/local/bin/node
1: /Users/mjr/work/node/process-args.js
2: one
3: two=three
4: four

大多数人都给出了很好的答案。我也想在这里做点贡献。我使用lodash库提供答案,以迭代我们在启动应用程序时传递的所有命令行参数:

1
2
3
4
5
6
7
8
9
10
11
12
// Lodash library
const _ = require('lodash');

// Function that goes through each CommandLine Arguments and prints it to the console.
const runApp = () => {
    _.map(process.argv, (arg) => {
        console.log(arg);
    });
};

// Calling the function.
runApp();

要运行以上代码,只需运行以下命令:

1
2
npm install
node index.js xyz abc 123 456

结果将是:

1
2
3
4
xyz
abc
123
456

process.argv是您的朋友,在node js中本机支持捕获命令行参数。见下例:

1
2
3
process.argv.forEach((val, index) => {
  console.log(`${index}: ${val}`);
})

将命令行参数传递给node.js程序的最佳方法是使用命令行接口(cli)

有一个漂亮的NPM模块,名为nodejs cli,您可以使用。

如果你想创建一个没有依赖性的,我在我的Github上有一个。如果你想查看它,它实际上非常简单和易于使用,点击这里。


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

1
2
3
4
5
6
7
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));
});