ฉันจะส่งผ่านอาร์กิวเมนต์บรรทัดคำสั่งไปยังโปรแกรม Node.js ได้อย่างไร


2414

ฉันมีเว็บเซิร์ฟเวอร์เขียนด้วยNode.jsและฉันต้องการที่จะเปิดตัวด้วยโฟลเดอร์เฉพาะ ฉันไม่แน่ใจว่าจะเข้าถึงอาร์กิวเมนต์ใน JavaScript ได้อย่างไร ฉันใช้โหนดเช่นนี้

$ node server.js folder

นี่server.jsคือรหัสเซิร์ฟเวอร์ของฉัน ความช่วยเหลือของ Node.js บอกได้ว่าสิ่งนี้เป็นไปได้:

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

ฉันจะเข้าถึงอาร์กิวเมนต์เหล่านี้ใน JavaScript ได้อย่างไร อย่างใดฉันไม่สามารถค้นหาข้อมูลนี้บนเว็บ

คำตอบ:


3047

วิธีมาตรฐาน (ไม่มีไลบรารี)

อาร์กิวเมนต์จะถูกเก็บไว้ใน process.argv

นี่คือโหนดเอกสารในการจัดการบรรทัดคำสั่ง args:

process.argvเป็นอาร์เรย์ที่มีอาร์กิวเมนต์บรรทัดคำสั่ง องค์ประกอบแรกจะเป็น 'โหนด' องค์ประกอบที่สองจะเป็นชื่อของไฟล์ 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

7
ฉันควรพิมพ์อะไรในพรอมต์คำสั่งเพื่อเรียกใช้สคริปต์ node.js พร้อมอาร์กิวเมนต์บรรทัดคำสั่ง
Anderson Green

8
UPDATE: ฉันพบคำตอบของคำถามข้างต้น stackoverflow.com/questions/12925802/…
Anderson Green

2
Minimistเป็นตัวแยกวิเคราะห์ที่ดีและเรียบง่าย
Guilherme Nagatomo

4
นอกจากนี้คุณยังสามารถเข้าถึงอาร์กิวเมนต์เดียวเมื่อคุณรู้ตำแหน่ง: ดัชนีอยู่process.argv[n]ที่ไหนn
Luca Steeb

6
องค์ประกอบที่ 2 (process.argv [1]) อาจเป็นหรือไม่เป็นไฟล์ js โหนดไวยากรณ์คำสั่งหรือnode [options] [ -e script | script.js ] [arguments] node debug script.js [arguments]ตัวอย่างเช่น: node --harmony script.js balalaหรือnode --no-deprecation --enable-ssl2 script.js balalaเราสามารถใช้process.execArgvกับprocess.argv
cuixiping

678

หากต้องการทำให้อาร์กิวเมนต์ธรรมดาเหมือนฟังก์ชั่นจาวาสคริปต์ปกติฉันจะทำเช่นนี้ในเชลล์สคริปต์ node.js ของฉัน:

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

โปรดทราบว่า arg แรกมักจะเป็นเส้นทางไปยัง nodejs และ arg ที่สองคือตำแหน่งของสคริปต์ที่คุณกำลังดำเนินการ


19
เพิ่งทราบว่าฉันเขียนคำตอบนี้ 4 ปีที่ผ่านมาและรหัสที่ฉันใช้อยู่ยังคงทำงานได้ดี 100% วันนี้ ยังคงความทันสมัยกับโหนดเวอร์ชันล่าสุดและยังคงเป็นปัญหาอยู่: มันเป็นเพียงเชลล์สคริปต์ง่ายๆ ไม่ใช่ส่วนหนึ่งของออบเจกต์ระดับโลกที่เต็มไปด้วยไลบรารี JS ฉันยังยืนอยู่ข้างหลังคำตอบของฉันในวันนี้ ฉันจะให้การอัปเดตอีกครั้งในอีก 4 ปี
Mauvis Ledford

55
var args = process.argv.splice(process.execArgv.length + 2);// node --harmony script.js balalaเพราะมีข้อยกเว้นของการใช้งานคำสั่งโหนดตัวอย่างเช่น: ดูprocess.execArgv
cuixiping

36
@cuixiping แต่execArgvมีไม่ได้ในargvดังนั้น 2 ก็พอ
Tommi Kyntola

7
หลังจากดูประวัติการแก้ไขของคำตอบนี้ฉันต้องการใช้เวลาสักครู่เพื่อเห็นอกเห็นใจกับ @MauvisLedford ไม่มีสิ่งใดน่ารำคาญพอ ๆ กับการแก้ไขโค้ดของคุณในชื่อของการตั้งค่าส่วนตัว (โดยไม่มีประโยชน์เชิงปริมาณในการบูต) ผู้ที่ทำเช่นนั้น: โยนออก
Jonathan Dumaine

12
ไม่ได้process.argv.splice(process.execArgv.length + 2)เพราะคำสั่งnode --harmony script.js --versionที่เป็นprocess.argv ธงบนจะไม่รวมอยู่ใน! ['/usr/local/bin/node', 'script.js', '--version']nodeprocess.argv
КонстантинВан

360

คำตอบที่ถูกต้องทันสมัยเพื่อให้มันใช้ห้องสมุด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' }

32
ที่จริงแล้วโซลูชันนี้มีประโยชน์มากขึ้นสำหรับการพัฒนาเครื่องมือบรรทัดคำสั่งที่มีแฟล็กและอาร์กิวเมนต์มากกว่ากัน
JK ABC

2
Imo นี่เป็นทางเลือกที่ง่ายกว่าสำหรับnpmjs.com/package/command-line-args
klodoma

5
@JKABC ฉันจะไม่เรียกคำตอบนี้ว่าถูกต้องที่สุดเนื่องจาก OP ขอให้เข้าถึงข้อมูลบรรทัดคำสั่งเล็กน้อย แต่ฉันยอมรับว่าทั้ง minimist และ command-line-args นั้นมีประโยชน์มากถ้าคุณวางแผนที่จะขยาย CLI ของคุณ
Justus Romijn

2
ฉันสงสัยว่าทำไม '-n5' ไม่ได้ผลิต 'n5: จริง' - นั่นจะสมเหตุสมผลสำหรับฉัน
Max Waterman

7
@ MaxWaterman: เนื่องจากตัวเลือกที่ขึ้นต้นด้วยเครื่องหมายขีดกลางควรเป็นอักขระตัวเดียวเท่านั้น สิ่งใดก็ตามที่ตามหลังตัวเลือกอักขระเดี่ยวจะถูกใช้เป็นอาร์กิวเมนต์สำหรับตัวเลือก (ไม่จำเป็นต้องมีช่องว่าง) การเริ่มตัวเลือกด้วยขีดกลางสองอัน (เช่น --n5) ควรสร้าง 'n5: true' นี่เป็นพฤติกรรมมาตรฐานสำหรับเครื่องมือบรรทัดคำสั่ง Unix ส่วนใหญ่ (แต่ไม่ใช่ทุกอย่างที่น่าเสียดาย)
Menno Smits

313

2018 คำตอบขึ้นอยู่กับแนวโน้มปัจจุบันในป่า:


การแยกวิเคราะห์อาร์กิวเมนต์ของวานิลลาจาวาสคริปต์:

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

ผลตอบแทนนี้:

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

เอกสารอย่างเป็นทางการ


แพ็กเกจ NPM ที่ใช้มากที่สุดสำหรับการแยกวิเคราะห์อาร์กิวเมนต์:

Minimist : สำหรับการแยกอาร์กิวเมนต์ขั้นต่ำ

Commander.js : โมดูลที่นำมาใช้ส่วนใหญ่สำหรับการแยกวิเคราะห์

Meow : ทางเลือกที่เบากว่าสำหรับ Commander.js

Yargs : การแยกอาร์กิวเมนต์ที่ซับซ้อนมากขึ้น (หนัก)

Vorpal.js : แอปพลิเคชันบรรทัดคำสั่งสำหรับผู้ใหญ่ / โต้ตอบพร้อมการแยกวิเคราะห์


76
"$ npm install -g yargs" ให้รหัส JavaScript 1.9 MB เมื่อไรที่ความบ้าคลั่งนี้จะสิ้นสุดลงเมื่อห้องสมุดตัวแยกวิเคราะห์ argv ต้องการโค้ดสองเมกะไบต์? พื้นผิวการโจมตีเพิ่มขึ้นเสีย RAM ฯลฯ ...
joonas.fi

9
Yargs เป็นเครื่องมือขนาดใหญ่ที่เกิดขึ้นกับอาร์กิวเมนต์บรรทัดคำสั่งแยกวิเคราะห์ ไม่มีความบ้าคลั่งขาดข้อมูล หากคุณต้องการอะไรที่เบากว่าให้ใช้ raw JS, Meow หรือ Minimist
dthree

1
"$ npm i yargs" -> 800 KB ที่นี่ฉันเดาว่าเจ้าของแพ็กเกจเรียนรู้ที่จะเพิกเฉยต่อไฟล์ที่ไม่เกี่ยวข้อง อย่างไรก็ตามยังมีขนาดใหญ่สำหรับโครงการที่โง่เง่า แต่มีขนาดเล็กเมื่อคุณต้องการความแข็งแกร่งและในโครงการขนาดใหญ่ที่คุณมีการพึ่งพาอยู่แล้ว ..
Andre Figueiredo

3
ฉันได้สร้างแพคเกจที่เรียกว่าwily-cliโดยมีเป้าหมายในการสร้างเครื่องมือที่ทรงพลังมากขึ้นปรับแต่งได้มากขึ้นและใช้งานง่ายกว่าชื่อใหญ่ที่ระบุไว้ สำหรับผู้ที่สนใจมีเพียง 94.6 KB เมื่อติดตั้ง
Jason

1
ต้นทุนการนำเข้า vscode บอกฉัน yargs (159.2K) ตอนนี้จริงแล้วเบากว่า meow (180.2K) นักแต่งเพลงยังคงเต้นได้ที่ 3.4K!
Shivam Tripathi

124

Optimist (node-optimist)

ลองใช้ห้องสมุด optimistมันดีกว่าการแยกตัวเลือกบรรทัดคำสั่งด้วยมือ

ปรับปรุง

Optimist เลิกใช้แล้ว ลองใช้yargsซึ่งเป็นทางแยกของ optimist


18
+1 สำหรับลิงก์ มีรายการตัวเลือกบรรทัดคำสั่งจำนวนมากที่github.com/joyent/node/wiki/modules#wiki-parsers-commandline
Thilo

7
Minimistเป็นผู้สืบทอดต่อผู้มองโลกในแง่ดีที่ไม่ยอมรับในขณะนี้ มันคือ "ความกล้าของผู้แยกวิเคราะห์ที่มองโลกในแง่ดีโดยไม่มีการตกแต่งที่เพ้อฝัน" 23 ล้านดาวน์โหลดในเดือนที่ผ่านมา (ณ วันที่ 12/2015)
aap

96

คำตอบที่ยอดเยี่ยมมากมายที่นี่ แต่ดูเหมือนจะซับซ้อน สิ่งนี้คล้ายกับวิธีที่สคริปต์ทุบตีเข้าถึงค่าอาร์กิวเมนต์และมีการจัดเตรียมมาตรฐานพร้อมกับ node.js ตามที่ MooGoo ชี้ให้เห็น (เพียงเพื่อทำให้เข้าใจได้สำหรับผู้ที่ยังใหม่กับ 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"

80

Commander.js

ใช้งานได้ดีสำหรับการกำหนดตัวเลือกการกระทำและข้อโต้แย้งของคุณ มันยังสร้างหน้าช่วยเหลือสำหรับคุณ

พลัน

ใช้งานได้ดีสำหรับการรับข้อมูลจากผู้ใช้ถ้าคุณชอบวิธีการโทรกลับ

ร่วม Prompt

ใช้งานได้ดีสำหรับการรับข้อมูลจากผู้ใช้ถ้าคุณชอบวิธีสร้าง


26
@Evan Carroll โปรดอย่าแก้ไขคำตอบของฉันเพื่อโปรโมตห้องสมุดฉันไม่ได้ใช้stackoverflow.com/posts/7483600/revisionsโดยเฉพาะอย่างยิ่งเนื่องจากคุณสมบัติที่ขาดหายไปของคุณหลังจากนั้นความคิดเห็นดังกล่าวควรถูกบันทึกไว้สำหรับความคิดเห็นหรือดึงคำขอไปยัง ผู้เขียนโมดูลไม่ใช่แก้ไขคำตอบของผู้อื่น
balupton

Commander.js ช่วยฉันออกมาจริงๆ ห้องสมุดอื่น ๆ จะไม่ทำงานกับคอมไพเลอร์ nexe แต่อันนี้ทำเพื่อหลอกลวง หากคุณต้องการรับ args เมื่อใช้ nexe ต้องแน่ใจว่าได้ส่ง -f ไปยังคอมไพเลอร์ nexe
pierce.jason

60

ไม่มี Libs ที่มีการจัดรูปแบบเป็นวัตถุแบบง่าย

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

1
เนื่องจากธงบางรายการมีรูปแบบยาวคุณจึงสามารถอธิบายเรื่องนี้ได้ แทนที่จะ= longArg[1]เขียนเป็นแบบ= longArg.length > 1 ? longArg[1] : true;นี้จะทำให้คุณผ่านการโต้แย้งประเภทนี้:node config/build.js --flag1 --flag2
tralston

ฉันชอบมัน. มันทำให้สายยาวไปหน่อยดังนั้นฉันก็เลิกกัน ขอบคุณที่บอกฉันเกี่ยวกับสิ่งนี้
Michael Warner

54

ห้องสมุด Stdio

วิธีที่ง่ายที่สุดในการแยกวิเคราะห์บรรทัดคำสั่งใน NodeJS คือการใช้โมดูลstdio แรงบันดาลใจจากgetoptยูทิลิตี้UNIX มันเป็นเรื่องเล็กน้อยดังต่อไปนี้:

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

ตัวเลือกการจัดกลุ่มได้รับการสนับสนุนเช่นกันดังนั้นคุณจึงสามารถเขียน-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)

คุณสามารถติดตั้งโมดูลstdioโดยใช้NPM :

npm install stdio

3
ตาม TOS ของ SO มันคุ้มค่าที่จะกล่าวถึง @sgmonda เป็นผู้ดูแลโมดูล แต่เพียงผู้เดียว) โมดูลที่ดีเพียงเล็กน้อย มีประโยชน์อย่างแน่นอน
Qix - MONICA ถูกยกเลิก

1
มีประโยชน์จริง ๆ แม้ว่าการอัปเดตล่าสุดคือ 30 ธันวาคม 2014 อาจไม่ได้รับการดูแลอย่างดีเหมือนแพคเกจอื่น ๆ
fearless_fool

lib ดี! TKS! มันเป็นการอัพเดทล่าสุดโดยที่มันมีฟังก์ชั่นที่ดีพอ
Pablo Ezequiel

มันผ่านมาระยะหนึ่งแล้ว แต่ฉันเพิ่งเปิดตัวเวอร์ชั่น 2 พร้อมสัญญาเต็มและการสนับสนุนตัวพิมพ์ดีด :-)
sgmonda

47

หากสคริปต์ของคุณชื่อ 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'

28

command-line-argsมีค่าดู!

คุณสามารถตั้งค่าตัวเลือกโดยใช้มาตรฐานสัญกรณ์หลัก ( เรียนรู้เพิ่มเติม ) คำสั่งเหล่านี้เทียบเท่าทั้งหมดตั้งค่าเดียวกัน:

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

การใช้งานขั้นสูง

นอกเหนือจากการใช้งานทั่วไปข้างต้นคุณสามารถกำหนดค่า command-line-args เพื่อยอมรับรูปแบบไวยากรณ์ขั้นสูงเพิ่มเติม

ไวยากรณ์คำสั่ง (สไตล์ git) ในรูปแบบ:

$ executable <command> [options]

ตัวอย่างเช่น.

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

ไวยากรณ์คำสั่งและคำสั่งย่อย (สไตล์นักเทียบท่า) ในรูปแบบ:

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

ตัวอย่างเช่น.

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

การสร้างคู่มือการใช้งาน

คู่มือการใช้งาน (พิมพ์โดยปกติเมื่อ--helpมีการตั้งค่า) สามารถสร้างขึ้นโดยใช้บรรทัดคำสั่งการใช้งาน ดูตัวอย่างด้านล่างและอ่านเอกสารสำหรับคำแนะนำวิธีการสร้าง

ตัวอย่างคู่มือการใช้งานทั่วไป

การใช้

พอลิเมอ CLIคู่มือการใช้งานเป็นตัวอย่างที่แท้จริงของชีวิตที่ดี

การใช้

อ่านเพิ่มเติม

มีอะไรอีกมากมายให้เรียนรู้โปรดดูวิกิสำหรับตัวอย่างและเอกสารประกอบ


@Lloyd นี้จะเชื่อมต่อออกเกิดขึ้นแล้ว - ที่นี่ Webstorm ส่งผ่านอาร์กิวเมนต์เพิ่มเติม
kboom

@ kboom ปัญหานั้นได้รับการแก้ไขโดยตัวเลือกpartialและ stopAtFirstUnknownดูเอกสาร
ลอยด์

23

มีแอพสำหรับสิ่งนั้น ดีโมดูล มากกว่าหนึ่งอาจเป็นร้อย

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

21

นี่คือโซลูชัน 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

หมายเหตุ: =ธรรมชาตินี้จะล้มเหลวเมื่อการโต้แย้งมี นี่เป็นเพียงการใช้งานที่ง่ายมาก


12

อาจเป็นความคิดที่ดีในการจัดการการกำหนดค่าของคุณในลักษณะรวมศูนย์โดยใช้บางอย่างเช่นnconf https://github.com/flatiron/nconf

ช่วยให้คุณทำงานกับไฟล์การกำหนดค่าตัวแปรสภาพแวดล้อมอาร์กิวเมนต์บรรทัดคำสั่ง


และนี่คือการกำหนดค่าอินเทอร์เฟซของฉันเองน้อยที่สุดอ่านได้อย่างเดียวสำหรับ nconf
Joel Purra

12

ไม่มีการใช้ librairies: using 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' }

เวอร์ชันที่ยาวขึ้นของคุณมีปัญหากับสตริงที่มีจุด
berliner

ทางออกที่ฉลาด! ถ้าฉันต้องการสนับสนุนทั้งสองcountและcตัวเลือกบรรทัดคำสั่ง ( cเป็นนามแฝง / shorcut สำหรับcount)
Alex Vang

นี่คือสิ่งที่สวยงาม! แต่จะไม่ใช้มาตรฐาน "หนึ่งขีดสำหรับคีย์ตัวอักษรหนึ่งตัวและขีดกลางสองอันสำหรับคีย์คำ" น่าเสียดายที่ตัวเลือกของฉันยาวเกินไปและน่าเกลียดที่จะโพสต์ที่นี่ดังนั้นฉันจะเพิ่มเป็นคำตอบอื่น
isacvale

10

ผ่านการแยกวิเคราะห์ข้อโต้แย้งเป็นกระบวนการที่ง่าย โหนดให้คุณสมบัติ process.argv ซึ่งเป็นอาร์เรย์ของสตริงซึ่งเป็นอาร์กิวเมนต์ที่ใช้เมื่อมีการเรียกใช้โหนด รายการแรกของอาร์เรย์คือ Node executable และรายการที่สองคือชื่อสคริปต์ของคุณ

หากคุณเรียกใช้สคริปต์ด้วย atguments ด้านล่าง

$ node args.js arg1 arg2

ไฟล์: args.js

console.log(process.argv)

คุณจะได้รับอาร์เรย์เช่น

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

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

1
ธุรกรรมซื้อคืนนี้ไม่สามารถใช้ได้บน github อีกต่อไป
steadweb

8

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 ใน maching ของคุณ (C: \ Program Files \ nodejs \ node.exe ')

1: ไดเรกทอรีของไฟล์โครงการของคุณ (proj.js)

2 : อาร์กิวเมนต์แรกของคุณไปยังโหนด (arg1)

3 : อาร์กิวเมนต์ที่สองของคุณไปยังโหนด (arg2)

4 : อาร์กิวเมนต์ที่สามของคุณไปยังโหนด (arg3)

ข้อโต้แย้งที่เกิดขึ้นจริงของคุณเริ่มต้นรูปแบบ2ndดัชนีของอาร์เรย์ที่เป็นargvprocess.argv[2]


7

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เพื่อใช้วิธีนี้


ไม่สามารถใช้งานได้mapคุณสมบัติไม่ได้กำหนดไว้
caram

6

คุณสามารถแยกอาร์กิวเมนต์ทั้งหมดและตรวจสอบว่ามีอยู่หรือไม่

ไฟล์: 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']);

4

ไม่มีห้องสมุด

หากคุณต้องการทำเช่นนี้ใน 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

ป.ล. โปรดแก้ไขรหัสในแผนที่และลดฟังก์ชั่นถ้าคุณพบคำตอบที่ดีกว่านี้ขอบคุณ;)


1
ฉันเห็นด้วย แต่อาจสั้นกว่านี้ไม่ได้หรือ let args = process.argv.slice(2).reduce((acc, arg) => { let [k, v] = arg.split('=') acc[k] = v return acc }, {})
Joseph Merdrignac

4

แม้ว่าคำตอบข้างต้นนั้นสมบูรณ์แบบและมีคนแนะนำให้ใช้เวลานานแล้วการใช้แพ็คเกจเป็นเรื่องง่ายมาก นี่เป็นแพคเกจที่ดีซึ่งทำให้การส่งผ่านอาร์กิวเมนต์ไปยังบรรทัดคำสั่งนั้นง่ายมาก

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

กรุณาเยี่ยมชมhttps://yargs.js.org/สำหรับข้อมูลเพิ่มเติม


Yargs ไม่ส่งผลกระทบต่อวิธีการส่งผ่านข้อโต้แย้งในบรรทัดคำสั่งมันช่วยในการอ่านในรหัสเท่านั้น
user3285954

4

การผ่านข้อโต้แย้งนั้นง่ายและการรับนั้นเป็นเพียงเรื่องของการอ่าน process.argv array Node ทำให้สามารถเข้าถึงได้จากทุกที่โดยทั่วไป แต่คุณแน่ใจว่าต้องการอ่านพวกเขาเป็นคู่ของคีย์ / ค่าดังนั้นคุณจะต้องมีสคริปต์ในการตีความ

โจเซฟ Merdrignac โพสต์หนึ่งที่สวยงามใช้ลด แต่มันอาศัยในkey=valueไวยากรณ์แทนและ-k value --key valueฉันเขียนมันน่าเกลียดมากขึ้นและนานขึ้นเพื่อใช้มาตรฐานที่สองนั้นและฉันจะโพสต์มันเป็นคำตอบเพราะมันไม่เหมาะกับคำอธิบาย แต่จะทำให้งานเสร็จ

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

3

วิธีที่ง่ายที่สุดในการดึงข้อมูลอาร์กิวเมนต์ใน 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


2

โซลูชั่น 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' }


1

process.argvเป็นเพื่อนของคุณการจับ args ของบรรทัดคำสั่งได้รับการสนับสนุนในโหนด JS ดูตัวอย่างด้านล่าง ::

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

0

ตามที่ระบุในโหนดเอกสารคุณสมบัติ 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

0

คนส่วนใหญ่ให้คำตอบที่ดี ฉันต้องการมีส่วนร่วมในสิ่งที่นี่ ฉันกำลังให้คำตอบโดยใช้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

0

วิธีที่ดีที่สุดในการส่งผ่านอาร์กิวเมนต์บรรทัดคำสั่งไปยังโปรแกรม Node.js คือการใช้ Command Line Interface (CLI)

มีโมดูลที่ดีที่สุดที่เรียกว่าnodejs-cliที่คุณสามารถใช้เป็น

หากคุณต้องการที่จะสร้างหนึ่งที่มีการอ้างอิงที่ไม่มีฉันมีหนึ่งบน Github ของฉันถ้าคุณอยากจะลองตรวจสอบออกก็จริงค่อนข้างง่ายและง่ายต่อการใช้งานคลิกที่นี่


0

โซลูชันไม่มีการพึ่งพาสไตล์ 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());
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.