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
For Loop For Htmlcollection Elements
JavaScript - Track Mouse Position
How to Set File Input Value When Dropping File on Page
Black and White Text Based on Background Image with CSS
Google Seo and Hidden Elements
Repeat Animation Every 3 Seconds
Detecting Touch Screen Devices with JavaScript
Is There a JavaScript Function That Can Pad a String to Get to a Determined Length
Check If Element Is Visible in Dom
Babel 6 Regeneratorruntime Is Not Defined
Difference Between Synchronous and Asynchronous Programming (In Node.Js)
Tainted Canvases May Not Be Exported
What Are Alternatives to Document.Write
How to Get Just Numeric Part of CSS Property with Jquery
How to Make Jquery UI Tabs Scroll Horizontally If There Are Too Many Tabs
Why Is Element Not Being Shown Before Alert