コマンドライン引数をNode.jsプログラムに渡すにはどうすればよいですか?

2010-12-04 javascript node.js arguments command-line-arguments

Node.jsで記述されたWebサーバーがあり、特定のフォルダーで起動したいと思います。 JavaScriptで引数にアクセスする方法がわかりません。私はこのようなノードを実行しています:

$ node server.js folder

ここでserver.jsは私のサーバーコードです。 Node.jsのヘルプでは、これが可能であるとしています:

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

JavaScriptでこれらの引数にどのようにアクセスしますか?どういうわけか私はこの情報をウェブ上で見つけることができませんでした。

Answers

標準メソッド(ライブラリなし)

引数はprocess.argv格納されprocess.argv

コマンドライン引数の処理に関するノードドキュメントは次のとおりです。

process.argvは、コマンドライン引数を含む配列です。最初の要素は「ノード」、2番目の要素は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シェルスクリプトで行います。

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

通常、最初の引数はnodejsへのパスで、2番目の引数は実行しているスクリプトの場所です。

Optimist(ノードオプティミスト)

オプティミストライブラリを確認してください。コマンドラインオプションを手動で解析するよりもはるかに優れています。

更新

Optimistは非推奨です。楽観主義者のアクティブなフォークであるyargsを試してください。

Commander.js

オプション、アクション、および引数の定義に最適です。また、ヘルプページが生成されます。

早速

コールバックアプローチが必要な場合は、ユーザーからの入力を取得するのに最適です。

共同プロンプト

ジェネレーターのアプローチが好きな場合は、ユーザーからの入力を取得するのに最適です。

nconf https://github.com/flatiron/nconfのようなものを使用して一元的な方法で構成を管理することはおそらく良い考えです

これは、構成ファイル、環境変数、コマンドライン引数の操作に役立ちます。

スクリプトの名前が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'

Stdioライブラリ

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, required: 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]);
}

グループ化されたオプションもサポートされているので、 -o -m代わりに-om書くことができます。

さらに、 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

すべての引数を解析して、それらが存在するかどうかを確認できます。

ファイル: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']);

ここにいくつかの素晴らしい答えがありますが、すべて非常に複雑に見えます。これは、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"

それが使用するこのため、最新の正しい答えminimistライブラリを。以前はノードオプティミストを使用していましたが、それ以降非推奨になりました。

これは、ミニミストのドキュメントから直接取った使用方法の例です。

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

そのためのアプリがあります。まあ、モジュール。ええと、複数、おそらく数百。

Yargsは楽しいものの1つであり、そのドキュメントは読みやすいです。

以下は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' ]

コマンドライン引数は一見の価値があります!

メインの表記基準を使用してオプションを設定できます( 詳細 )。これらのコマンドはすべて同等であり、同じ値を設定します。

$ 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プロパティはセッター関数であり(提供された値はこれを介して渡されます)、受け取った値を完全に制御できます。

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
}

高度な使用法

上記の典型的な使用法に加えて、より高度な構文形式を受け入れるようにコマンドライン引数を構成できます。

の形式のコマンドベースの構文 (gitスタイル):

$ executable <command> [options]

例えば。

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

次の形式のコマンドおよびサブコマンド構文 (dockerスタイル)。

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

例えば。

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

使用ガイドの生成

使用ガイド(通常--helpが設定されている場合に印刷され--help )は、 command-line-usageを使用して生成できます 。以下の例を参照し、それらを作成する方法についてはドキュメントをお読みください。

典型的な使用ガイドの例。

使用法

Polymer-CLIの使用ガイドは、実際の良い例です。

使用法

参考文献

学ぶべきことはまだたくさんあります。例とドキュメントについてはwikiを参照しください。

引数の受け渡し、解析は簡単なプロセスです。 Nodeは、Nodeが呼び出されたときに使用された引数である文字列の配列であるprocess.argvプロパティを提供します。 配列の最初のエントリはノード実行可能ファイルで、2番目のエントリはスクリプトの名前です。

以下の引数でスクリプトを実行すると

$ node args.js arg1 arg2

ファイル:args.js

console.log(process.argv)

あなたはのような配列を取得します

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

野生の現在の傾向に基づく2018年の回答:


バニラJavaScript引数の解析:

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

これは次を返します:

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

公式ドキュメント


引数の解析に最もよく使用されるNPMパッケージ:

ミニミスト :最小限の引数解析用。

Commander.js :引数の解析に最も採用されているモジュール。

ニャー :Commander.jsの軽量版

Yargs :より高度な引数解析(重い)。

Vorpal.js :引数の解析が可能な成熟した対話型のコマンドラインアプリケーション。

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を使用してコマンドライン引数に到達できます。そして、以下の解決策を使用して引数をオブジェクトに解析するので、必要なものを名前で取得できます。

var system = require('system');

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

今、あなたは引数のインデックスを知る必要はありません。 args.whateverように使用しargs.whatever

注:使用するには、 file.js x=1 y=2ような名前付き引数を使用する必要があります このソリューション。

必要な場合の簡単なスニペット:

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

ライブラリなし

これをバニラ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

psマップのコードを修正し、関数を減らしてください よりエレガントな解決策を見つけた場合は、感謝します;)

ライブラリなし: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' }

ノードのドキュメントに記載されています 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

ほとんどの人が良い答えを出しています。ここでも何か貢献したいと思います。アプリの起動時に渡すすべてのコマンドライン引数を反復処理するために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

Node.jsで引数を取得する最も簡単な方法は、process.argv配列を使用することです。これは、追加のライブラリをインポートせずに使用できるグローバルオブジェクトです。前に示したように、Node.jsアプリケーションに引数を渡すだけでよく、これらの引数は、process.argv配列を介してアプリケーション内でアクセスできます。

process.argv配列の最初の要素は、常にノードの実行可能ファイルを指すファイルシステムパスです。 2番目の要素は、実行されているJavaScriptファイルの名前です。 3番目の要素は、ユーザーが実際に渡した最初の引数です。

'use strict';

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

このスクリプトが実行するのは、process.argv配列をループして、インデックスに格納されている要素と共にインデックスを出力することだけです。受け取っている引数とその順序に疑問がある場合は、デバッグに非常に役立ちます。

yargsなどのライブラリを使用して、commnadline引数を操作することもできます。

process.argvは友だちです。コマンドライン引数のキャプチャはNode JSでネイティブにサポートされています。以下の例を参照してください:

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

proj.js

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

ターミナル:

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

結果:

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.

説明:

0 :マシン内のnode.exeのディレクトリ(C:\ Program Files \ nodejs \ node.exe ')

1 :プロジェクトファイルのディレクトリ。 (proj.js)

2 :ノードへの最初の引数(arg1)

3 :ノードへの2番目の引数(arg2)

4 :ノードへの3番目の引数(arg3)

実際の引数は、 argv配列の2ndインデックス、つまりprocess.argv[2]から始まります。

名前付き引数の私の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

注:引数に=が含まれている場合、これは当然失敗します。これは非常に単純な使用法のみです。

上記の答えは完璧で、誰かがすでにyargsを提案していますが、パッケージの使用は本当に簡単です。 これは、コマンドラインへの引数の受け渡しを非常に簡単にする素晴らしいパッケージです。

npm i yargs
const yargs = require("yargs");
const argv = yargs.argv;
console.log(argv);

詳細については、 https://yargs.js.org/にアクセスしてください。

フラグが単純なオブジェクトにフォーマットされたライブラリはありません

function getArgs () {
    const args = {};
    process.argv
        .slice(2, process.argv.length)
        .forEach( arg => {
        // long arg
        if (arg.slice(0,2) === '--') {
            const longArg = arg.split('=');
            const longArgFlag = longArg[0].slice(2,longArg[0].length);
            const longArgValue = longArg.length > 1 ? longArg[1] : true;
            args[longArgFlag] = longArgValue;
        }
        // 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);

シンプルな

入力

node test.js -D --name=Hello

出力

{ D: true, name: 'Hello' }

現実の世界

入力

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

出力

{ 
  l: true,
  H: true,
  R: true,
  s: true,
  ip: '127.0.0.1',
  port: '8080',
  env: 'dev'
}

コマンドライン引数をNode.jsプログラムに渡す最善の方法は、コマンドラインインターフェイス(CLI)を使用することです。

使用できるnodejs-cliと呼ばれる気の利いたnpmモジュールがあります。

依存関係のないものを作成したい場合は、Githubで入手できます。確認したい場合は、非常にシンプルで使いやすいです 。ここをクリックしてください

引数を渡すのは簡単で、引数を受け取るのは単にprocess.argv配列を読み取るだけです。基本的に、Nodeはどこからでもアクセスできます。ただし、必ずキーと値のペアとして読み取る必要があるので、スクリプトを解釈して解釈する必要があります。

Joseph Merdrignacはreduceを使用して美しいものを投稿しましたが、それは-k value--key valueではなくkey=value構文に依存していました。私はその2番目の標準を使用するためにずっと醜く、より長く書き直しました。コメントとしては適合しないので、それを回答として投稿します。しかし、それは仕事を成し遂げます。

   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は次のオブジェクトを提供します

 args = { "alpha":true, "beta":true, "c":true, "h":true, "a":true, "r":true "l":true, "i":true, "e":"delta", "echo":"foxtrot" } 
 args = { "alpha":true, "beta":true, "c":true, "h":true, "a":true, "r":true "l":true, "i":true, "e":"delta", "echo":"foxtrot" } 
 args = { "alpha":true, "beta":true, "c":true, "h":true, "a":true, "r":true "l":true, "i":true, "e":"delta", "echo":"foxtrot" } 
 args = { "alpha":true, "beta":true, "c":true, "h":true, "a":true, "r":true "l":true, "i":true, "e":"delta", "echo":"foxtrot" } 
 args = { "alpha":true, "beta":true, "c":true, "h":true, "a":true, "r":true "l":true, "i":true, "e":"delta", "echo":"foxtrot" } 
 args = { "alpha":true, "beta":true, "c":true, "h":true, "a":true, "r":true "l":true, "i":true, "e":"delta", "echo":"foxtrot" } 
 args = { "alpha":true, "beta":true, "c":true, "h":true, "a":true, "r":true "l":true, "i":true, "e":"delta", "echo":"foxtrot" } 
 args = { "alpha":true, "beta":true, "c":true, "h":true, "a":true, "r":true "l":true, "i":true, "e":"delta", "echo":"foxtrot" } 
 args = { "alpha":true, "beta":true, "c":true, "h":true, "a":true, "r":true "l":true, "i":true, "e":"delta", "echo":"foxtrot" } 
 args = { "alpha":true, "beta":true, "c":true, "h":true, "a":true, "r":true "l":true, "i":true, "e":"delta", "echo":"foxtrot" } 
 args = { "alpha":true, "beta":true, "c":true, "h":true, "a":true, "r":true "l":true, "i":true, "e":"delta", "echo":"foxtrot" } 
 args = { "alpha":true, "beta":true, "c":true, "h":true, "a":true, "r":true "l":true, "i":true, "e":"delta", "echo":"foxtrot" } 
 

ES6スタイルの非依存ソリューション:

const longArgs = arg => {
    const [ key, value ] = arg.split('=');
    return { [key.slice(2)]: value || true }
};

const flags = arg => [...arg.slice(1)].reduce((flagObj, f) => ({ ...flagObj, [f]: true }), {});


const args = () =>
    process.argv
        .slice(2)
        .reduce((args, arg) => ({
            ...args,
            ...((arg.startsWith('--') && longArgs(arg)) || (arg[0] === '-' && flags(arg)))
        }), {});
console.log(args());

標準入力に基づいた引数の解析( --key=value

const argv = (() => {
    const arguments = {};
    process.argv.slice(2).map( (element) => {
        const matches = element.match( '--([a-zA-Z0-9]+)=(.*)');
        if ( matches ){
            arguments[matches[1]] = matches[2]
                .replace(/^['"]/, '').replace(/['"]$/, '');
        }
    });
    return arguments;
})();

コマンド例

node app.js --name=stackoverflow --id=10 some-another-argument --text="Hello World"

argvの結果: console.log(argv)

{
    name: "stackoverflow",
    id: "10",
    text: "Hello World"
}

ライブラリなしのTypeScriptソリューション:

interface IParams {
  [key: string]: string
}

function parseCliParams(): IParams {
  const args: IParams = {};
  const rawArgs = process.argv.slice(2, process.argv.length);
  rawArgs.forEach((arg: string, index) => {
    // Long arguments with '--' flags:
    if (arg.slice(0, 2).includes('--')) {
      const longArgKey = arg.slice(2, arg.length);
      const longArgValue = rawArgs[index + 1]; // Next value, e.g.: --connection connection_name
      args[longArgKey] = longArgValue;
    }
    // Shot arguments with '-' flags:
    else if (arg.slice(0, 1).includes('-')) {
      const longArgKey = arg.slice(1, arg.length);
      const longArgValue = rawArgs[index + 1]; // Next value, e.g.: -c connection_name
      args[longArgKey] = longArgValue;
    }
  });
  return args;
}

const params = parseCliParams();
console.log('params: ', params);

入力: ts-node index.js -p param --parameter parameter

出力: { p: 'param ', parameter: 'parameter' }

Related