How to Pass Command Line Arguments to a Node.Js Program

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

Standard Method (no library)

The arguments are stored in process.argv

Here are the node docs on handling command line args:

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.

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

This will generate:

$ 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

How to pass parameter when executing a node.js script?

You just need to call as many arguments as you want, like:

node myscript.js arg1 arg2 arg3

And you recover them like:

console.log(process.argv[2]);

How can I pass an argument into my Javascript code from command line?

In many programs (including node), arguments can be passed to your script through something
we call flags.

Node itself is a program and when you write node foo.js, foo.js itself is an argument to the node program. To pass arguments through command line use flags via double dash.

Example:

node foo.js bar/baz/index.html 

now the value can be accessed through process.argv which is an array of all the arguments passed to it. It will look something like this

['node.exe', 'foo.js', 'bar/baz/indez.html']

How can I execute command line arguments in a node.js script

Certainly worth asking! JS can be a confusing language to learn.

If a function returns a Promise (as find does) then logging what it returns is not normally very useful. A Promise is something which will at some point be able to potentially give some sort of useful value.

The .then part of your function is where you can use the value that the promise contains. A Promise will run the function contained in .then once it has got the value back. So doing something like:

const find = require('local-devices');

// Find all local network devices.
find().then(devices => {
console.log(devices);
})

Means that when the function which finds the devices has got a value back, it will log that value.

Commnd line argument in node js

So what this error is telling you is that you are referencing the variable message which has not been defined. In order to define both message and user you are going to need to fetch those values from the command line arguments.

In order to do this we are going to access them via process.argv. Assuming that you are passing message first and user second then the resulting code would look something like this.

// The first argument is the node executable
// The second is the script file name
let message = process.argv[2],
user = process.argv[3];

function myTest(message, user) {
console.log(message + ": "+ user);
}

myTest(message, user);

For more information on command line arguments in Node.js please see this post.

How do I use new line characters (\n) with command line arguments in node?

To explain what's going on, have a look at the following:

const str1 = process.argv[2];
const str2 = '\n';

console.log(Buffer.from(str1)) // prints <Buffer 5c 6e> if '\n' is passed as an argument to the script
console.log(Buffer.from(str2)) // prints <Buffer 0a>

Looking the buffer values up in the ASCII table, you'll find:

10  0a  00001010    
   LF  Line Feed
92 5c 01011100 \ \ backslash
110 6e 01101110 n n

So as you can see the argument '\n' is not interpreted as a Line Feed character but literally as \ and n.

To fix this, using bash you can pass the argument through $'<...>' expansion forcing escape sequences to be interpreted:

node test.js $'Line1\nLine2'

This will print

Line1
Line2

to the console as expected.

How to pass command line arguments to NodeJS launched from an executable script

One option is to write a little wrapper script that uses the current process execPath to run child_process.execFile.

So the sample here is to be able to do

node --expose-http2 --zero-fill-buffers -r ./some-module.js ./test.js

but not actually write that out, instead have wrap.js inject the args:

node ./wrap.js ./test.js

I tested running this via npm in a package.json, and it works fine. I tested that it was working by having some-module.js stick a value on the global object, and then logging it in test.js.

Files involved:

wrap.js

const child_process = require('child_process');

const nodeArgs = ['--expose-http2', '--zero-fill-buffers', '-r', './some-module.js'];
const runTarget = process.argv[2];

console.log('going to wrap', runTarget, 'with', nodeArgs);

const finalArgs = nodeArgs.concat(runTarget).concat(process.argv.slice(2));

const child = child_process.execFile(
process.execPath,
finalArgs,
{
env: process.env,
cwd: process.cwd(),
stdio: 'inherit'
}, (e, stdout, stderr) => {
console.log('process completed');
if (e) {
process.emit('uncaughtException', e);
}
});

child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);

and

some-module.js

global.testval = 2;

and

test.js

console.log('hi guys, did the wrap work?', global.testval)

EDIT: So upon further thought, this solution really only satisfies wrapping the initial runner. But most tools, such as mocha re-spawn a sub process which would then lose this effect. To really get the job done, you can proxy each of the child process calls and somewhat enforce that calls to spawn and such also include your args.

I rewrote the code to reflect this. Here's a new setup:

package.json

{
"scripts": {
"test": "node -r ./ensure-wrapped.js node_modules/mocha/$(npm view mocha bin.mocha) ./test.js"
},
"dependencies": {
"mocha": "^5.1.0"
}
}

ensure-wrapped.js

const child_process = require('child_process');

// up here we can require code or do whatever we want;

global.testvalue = 'hi there'
const customParams = ['--zero-fill-buffers'];

// the code below injects itself into any child process's spawn/fork/exec calls
// so that it propogates

const matchNodeRe = /((:?\s|^|\/)node(:?(:?\.exe)|(:?\.js)|(:?\s+)|$))/;
const ensureWrappedLocation = __filename;

const injectArgsAndAddToParamsIfPathMatchesNode = (cmd, args, params) => {
params.unshift(...customParams);
params.unshift(args);
if (!Array.isArray(args)) { // all child_proc functions do [] optionally, then other params
args = []
params.unshift(args);
}

if (!matchNodeRe.test(cmd)) {
return params;
}

args.unshift(ensureWrappedLocation);
args.unshift('-r');

return params;
}

child_process._exec = child_process.exec;
child_process.exec = (cmd, ...params) => {
// replace node.js node.exe or /path/to/node to inject -r ensure-wrapped.js ...args..
// leaves alone exec if it isn't calling node
cmd = cmd.replace(matchNodeRe, '$1 -r ' + ensureWrappedLocation + ' ');
return child_process._exec(cmd, ...params)
}
child_process._execFile = child_process.execFile;
child_process.execFile = (path, args, ...params) => {
params = injectArgsAndAddToParamsIfPathMatchesNode(path, args, params);
return child_process._execFile(path, ...params)
}
child_process._execFileSync = child_process.execFileSync;
child_process.execFileSync = (path, args, ...params) => {
params = injectArgsAndAddToParamsIfPathMatchesNode(path, args, params);
return child_process._execFileSync(path, ...params);
}
child_process._execSync = child_process.execSync;
child_process.execSync = (cmd, ...params) => {
cmd = cmd.replace(matchNodeRe, '$1 -r ' + ensureWrappedLocation + ' ');
return child_process._exec(bin, ...args)
}
child_process._fork = child_process.fork;
child_process.fork = (module, args, ...params) => {
params = injectArgsAndAddToParamsIfPathMatchesNode(process.execPath, args, params);
return child_process._fork(module, ...params);
}
child_process._spawn = child_process.spawn;
child_process.spawn = (cmd, args, ...params) => {
params = injectArgsAndAddToParamsIfPathMatchesNode(cmd, args, params);
return child_process._spawn(cmd, ...params)
}
child_process._spawnSync = child_process.spawnSync;
child_process.spawnSync = (cmd, args, ...params) => {
params = injectArgsAndAddToParamsIfPathMatchesNode(cmd, args, params);
return child_process._spawnSync(cmd, ...params);
}

test.js

describe('test', () => {
it('should have the global value pulled in by some-module.js', (done) => {
if (global.testvalue !== 'hi there') {
done(new Error('test value was not globally set'))
}
return done();
})
})

Please never put code like this into a node module that's published. modifying the global library functions is pretty bad.



Related Topics



Leave a reply



Submit