What are Command Line Arguments?
Command line arguments are strings of text used to pass additional information to a program when an application is run through the command line interface (CLI) of an operating system. Command line arguments typically include information used to set configuration or property values for an application.
In most cases the arguments are passed after the program name in your prompt. An example of the syntax of command line arguments looks like this:
$ [runtime] [script_name] [argument-1 argument-2 argument-3 ... argument-n]
Here runtime can be anything that executes a program/script e.g. sh
, java
, node
, etc. The arguments are usually separated by a space - however there are some runtimes that use commas to distinguish between multiple command line arguments. Also, depending on the program, you can pass arguments in the form of key-value pairs, which we'll see later in this article.
Why Use Command Line Arguments?
The following are some of the major benefits of using command line arguments:
- You can pass information to an application before it starts. This is particularly useful if you want to perform large number configuration settings.
- Command line arguments are passed as strings to your program. String data types can easily be converted to other data types within an application, making the arguments very flexible.
- You can pass an unlimited number of arguments via the command line.
- Command line arguments are used in conjunction with scripts and batch files, which is particularly useful for automated testing.
And here are some of the disadvantages of using them:
- The biggest disadvantage of passing information via the command line is that the interface has a steep learning curve, so it's difficult for most people to use unless they have a good deal of experience using CLI tools.
- Command line applications can be difficult to use unless you're using a desktop or laptop computer, so they're not typically used on smaller devices like phones or tablets.
Passing Command Line Arguments in Node.js
Like many other languages, Node.js applications also accept command line arguments. By default Node will handle accepting the arguments for you, but there are also some great third party packages that add some very useful features.
In this section we'll show you how to use arguments via the built-in way (process.argv
), as well as with the popular packages minimist
and yargs
.
Using process.argv
The simplest way of retrieving arguments in Node.js is via the process.argv
array. This is a global object that you can use without importing any additional libraries to use it. You simply need to pass arguments to a Node.js application, just like we showed earlier, and these arguments can be accessed within the application via the process.argv
array.
The first element of the process.argv
array will always be a file system path pointing to the node
executable. The second element is the name of the JavaScript file that is being executed. And the third element is the first argument that was actually passed by the user.
To avoid confusion, I'd like to remind you beginners out there that JavaScript uses zero-based indexes on arrays (like many other languages), which means that first element will be stored at "0th" index and last element will be stored at "n-1" index, where "n" is the total number of elements in the array.
Now let's write a simple Node script that prints all of the command line arguments passed to the application, along with their index. Copy and paste the following code to a file named processargv.js
.
'use strict';
for (let j = 0; j < process.argv.length; j++) {
console.log(j + ' -> ' + (process.argv[j]));
}
All this script does is loop through the process.argv
array and print the indexes, along with the elements stored in those indexes. It's very useful for debugging if you ever question what arguments you're receiving, and in what order.
Now, to run this type the following command. Just make sure you are in the directory where the processargv.js
file is saved.
$ node processargv.js tom jack 43
Here we are passing three arguments to the processargv.js
program. You will see that "tom" will be stored at 2nd index while "jack" and "43" will be stored at 3rd and 4th indexes, respectively. The output should look something like this:
$ node processargv.js tom jack 43
0 -> /Users/scott/.nvm/versions/node/v4.8.0/bin/node
1 -> /Users/scott/javascript/processargv.js
2 -> tom
3 -> jack
4 -> 43
You can see that the first index contains the path to our node
executable (which will likely have a different path than mine), the second index contains the path to the script file, and the rest of the indexes contain the arguments that we passed in their respective sequence.
Using the minimist Module
Another way to retrieve command line arguments in a Node.js application is using the minimist module. The minimist
module will parse arguments from the process.argv
array and transform it into an easier-to-use associative array. In the associative array you can access the elements via index names in addition to the index numbers. Take a look at the following example.
'use strict';
const args = require('minimist')(process.argv.slice(2));
console.log(args);
console.log(args.i);
Save the above code in minimist.js
. In the above code we use the slice
method of the process.argv
global object. The slice
method, in this case, removes all prior array elements starting from the index passed to it as the parameter. Here we know that the arguments we manually pass are stored starting from the second index, we passed 2 to the slice function. We then printed the entire args
object. We also printed a single element of the array using the named index i.e. "i", rather than the index number.
Now when we pass an argument to this program we can also specify the character by which we want to access the element. Since in the script we use the "i" index name to access the element, we have to specify the element stored at this index. Take a look at the script to execute the above program.
$ node minimist.js –i jacob –j 45
Notice here we specified "i" as the name for the second index; the value stored at that index is "jacob". Similarly the third index is named as "j" and the value at this index is 45. The output of above command will be as follows:
$ node minimist.js -i jacob -j 45
{ _: [], i: 'jacob', j: 45 }
jacob
While not as feature-rich as some of the other argument-parsing modules (see yargs
below), minimist has a few useful features you may want to look into, like aliasing and defaults.
If you set an alias, then the caller of your program can use the alias in addition to the regular option name. This is useful if you want to have a shorthand notation for your options, as seen below:
'use strict';
const minimist = require('minimist');
let args = minimist(process.argv.slice(2), {
alias: {
h: 'help',
v: 'version'
}
});
console.log('args:', args);
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
Calling this code with the -h
option sets both h: true
and help: true
in the output args:
$ node minimist-alias.js -h
args: { _: [], h: true, help: true }
As for minimist
's defaults feature, if no value is passed for an option then the default you set in your program will be used automatically.
'use strict';
const minimist = require('minimist');
let args = minimist(process.argv.slice(2), {
default: {
port: 8080
},
});
console.log('args:', args);
Calling this code without the -port
option still yields you with a port
value in the returned args
object:
$ node minimist-defaults.js
args: { _: [], port: 8080 }
For more options, check out the README.
Using the yargs
Module
Another module to help you parse command line arguments passed to Node programs is the yargs module. Using this module you can pass arguments in the form of key-value pairs and later access the argument values in your program using corresponding keys.
Note: You can install the yargs
module with the following command:
$ npm install yargs
Now, take a look at the following script:
'use strict';
const args = require('yargs').argv;
console.log('Name: ' + args.name);
console.log('Age: ' + args.age);
In the above script we display the values provided for the 'name' and 'age' arguments, which were passed via the command line. Now save the above script in a file named yargs.js
.
Note: When you execute the above program you have to pass values for 'name' and 'age' arguments, otherwise undefined
will be given for the arguments by default and you will see undefined
written to the console.
To execute above program, execute the following command in your prompt:
$ node yargs.js --name=jacob --age=45
Here we are passing values for both name and age arguments. The output of above script will look like this:
$ node yargs.js --name=jacob --age=45
Name: jacob
Age: 45
The yargs
package is a very powerful one, not only providing the standard argument-parsing features but many advanced features as well. While we won't go through all of the features in this article, we'll at least touch on one of its most popular features.
One of the most powerful ways to use yargs
is the .command()
option, which helps you create, expose, and call Node functions via the command line. Here is a simple example of this feature in action:
'use strict';
const argv = require('yargs')
.command('upload', 'upload a file', (yargs) => {}, (argv) => {
console.log('Uploading your file now...');
// Do stuff here
}).argv;
Calling this program with the "upload" command will invoke the function you passed to it, which in this case just prints to the command line. However, I'm sure you can imagine passing a much more capable function that uses the parsed argv
object to determine what file to send where.
For example, this command could be called like this (assuming the code above is stored in a file called s3-tool.js
:
$ node s3-tool.js upload --file=my-file.txt --bucket=my-s3-bucket
Uploading your file now...
And you don't have to stop there, you can even create a default command:
'use strict';
const argv = require('yargs')
.command('*', 'the default command handler', () => {}, (argv) => {
console.log('This function is called by default');
}).argv;
The .command()
feature is even powerful enough to infer your required and optional parameters from a string:
'use strict';
const yargs = require('yargs');
yargs.command('login <username> [password]', 'authenticate with the server').argv
For more information on the advanced features, check out the yargs
advanced topics documentation.
Conclusion
It might be a bit surprising to you, but as you may have noticed, argument parsing can actually be a pretty complex topic. Depending on your needs you can make it as simple or complicated as you want. Regardless, there is a suitable solution for all needs, whether it's the basic process.argv
array or the powerful yargs
package.
How have you used minimist
and yargs
to create CLI programs? Let us know in the comments!