首页 文章

如何将命令行参数传递给Node.js程序?

提问于
浏览
1927

我有一个用Node.js编写的Web服务器,我想用特定的文件夹启动 . 我这样运行节点'm not sure how to access arguments in JavaScript. I'm:

$ node server.js folder

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

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

我如何在JavaScript中访问这些参数?不知何故,我无法在网上找到这些信息 .

26 回答

  • 23

    Commander.js

    适用于定义选项,操作和参数 . 它还会为您生成帮助页面 .

    及时

    如果您喜欢回调方法,那么非常适合从用户那里获取输入 .

    共同提示

    如果您喜欢生成器方法,那么非常适合从用户那里获取输入 .

  • 6

    在Node.js中检索参数的最简单方法是通过process.argv数组 . 这是一个全局对象,您可以使用它而无需导入任何其他库来使用它 . 您只需将参数传递给Node.js应用程序,就像我们之前展示的那样,并且可以通过process.argv数组在应用程序中访问这些参数 .

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

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

    所有这些脚本都循环遍历process.argv数组并打印索引以及存储在这些索引中的元素 . 如果你质疑你接收的是什么参数,以及按什么顺序排序,它对于调试非常有用 .

    您还可以使用yargs等库来处理commnadline参数 .

  • 0
    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'
    
  • 2550

    这里有几个很好的答案,但这一切似乎都非常复杂 . 这与bash脚本访问参数值的方式非常相似,并且已经像mooGoo指出的那样已经为node.js提供了标准 . (只是为了让那些对node.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"
    
  • 6

    Stdio Library

    在NodeJS中解析命令行参数的最简单方法是使用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
    

    如果未给出强制选项(在错误消息之前)或错误指定(例如,如果为选项指定单个arg且需要2),则还会显示上一条消息 .

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

    npm install stdio
    
  • 69

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

    如果您使用以下参数运行脚本

    $ node args.js arg1 arg2
    

    文件:args.js

    console.log(process.argv)
    

    你会得到类似的数组

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

    标准方法(无库)

    参数存储在 process.argv

    这是the node docs on handling command line args:

    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
    
  • 78

    没有librairies:使用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' }
    
  • 9

    command-line-args值得一看!

    您可以使用主标记标准(learn more)设置选项 . 这些命令都是等效的,设置相同的值:

    $ 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
    

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

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

    接下来,使用commandLineArgs()解析选项:

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

    options 现在看起来像这样:

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

    高级用法

    除了上面的典型用法,您还可以配置命令行参数以接受更高级的语法表单 .

    Command-based syntax(git style)的形式:

    $ executable <command> [options]
    

    例如 .

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

    形式为Command and sub-command syntax(码头 Worker 样式):

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

    例如 .

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

    使用指南生成

    可以使用command-line-usage生成使用指南(通常在设置 --help 时打印) . 请参阅下面的示例和read the documentation以获取有关如何创建它们的说明 .

    典型的使用指南示例 .

    usage
    polymer-cli使用指南是一个很好的现实生活中的例子 .

    usage

    进一步阅读

    还有很多需要学习的内容,请参阅the wiki以获取示例和文档 .

  • 36

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

    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));
    });
    
  • 522

    使用 nconf https://github.com/flatiron/nconf之类的东西以集中方式管理配置可能是个好主意 .

    它可以帮助您使用配置文件,环境变量,命令行参数 .

  • -4

    您可以使用 system.args 访问命令行参数 . 我使用下面的解决方案将参数解析为一个对象,所以我可以通过名称得到我想要的那个 .

    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这样的命名参数来使用此解决方案 .

  • 3

    如果您的脚本名为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'
    
  • 20

    这是使用minimist库的最新正确答案 . 我们曾经使用过node-optimist但它已经被弃用了 .

    以下是直接从最小化文档中使用它的示例:

    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' }
    
  • 9

    有一个应用程序 . 好吧,模块 . 好吧,不止一个,可能是几百个 .

    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' ]
    
  • 0

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

    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']);
    
  • 112

    proj.js

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

    Terminal:

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

    Result:

    0 'C:\\Program Files\\nodejs\\node.exe'
    1 'C:\\Users\\Nouman\\Desktop\\Node\\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.
    

    Explaination:

    0 :机器中的node.exe目录(C:\ Program Files \ nodejs \ node.exe')

    1 :项目文件的目录 . (proj.js)

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

    3 :节点的第二个参数(arg2)

    4 :节点的第三个参数(arg3)

    你的实际参数从 2nd 索引 argv 数组开始,即 process.argv[2] .

  • 10

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

    // 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();
    

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

    npm install
    node index.js xyz abc 123 456
    

    结果将是:

    xyz 
    abc 
    123
    456
    
  • 8

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

    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)
    

    例:

    $ node test.js foo=bar fizz=buzz
    bar
    buzz
    

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

  • 272

    Optimist(节点乐观主义者)

    查看optimist library,它比手动解析命令行选项要好得多 .

    Update

    Optimist已被弃用 . 试试yargs这是乐观主义的活跃分支 .

  • -1

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

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

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

    启动Node.js进程:

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

    会产生输出:

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

    根据当前的野外趋势回答

    2018:


    香草javascript参数解析:

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

    返回:

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

    Official docs


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

    Minimist :用于最小化参数解析 .

    Commander.js :最常用的模块用于参数解析 .

    Meow :Commander.js的替代品

    Yargs :更复杂的参数解析(重) .

    Vorpal.js :带有参数解析的成熟/交互式命令行应用程序 .

  • 0

    process.argv 是你的朋友,在Node JS中本机支持捕获命令行args . 见下面的例子::

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

    你也可以使用yargs包它会让事情变得容易!在这里你去:) Yargs

  • 5

    要像普通的javascript函数那样规范化参数,我会在node.js shell脚本中执行此操作:

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

    请注意,第一个arg通常是nodejs的路径,第二个arg是您正在执行的脚本的位置 .

  • 40

    没有库

    如果您想在vanilla JS / ES6中执行此操作,可以使用以下解决方案

    仅在 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
    

    附:如果你找到更优雅的解决方案,请更正 Map 中的代码并减少功能,谢谢;)

相关问题