Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / operating-systems / Linux

Using getopts in shell programming to handle command line arguments

5.00/5 (2 votes)
17 Feb 2015CPOL6 min read 15.9K   46  
Using getopts in shell scripting to handle command line arguments.

Introduction

As a developer in LINUX\UNIX environment we have to write shell scripts to automate certain routine tasks or create a complete workflow (or batch) of our application using scripts and tools like Autosys.  When we write scripts, usually we want to pass command line arguments aka parameters to give inputs or control how our scripts work. All shells provide very basic way of passing command line parameters to script and is usually not enough if script provides complex functionality. The getopts command provides an easy way to handle command line arguments especially the optional arguments.  

The getopts is implemented differently in different versions of UNIX\LINUX and can confuse a lot when you search for it online. In this article I am going to discuss the core functionality and some interesting finds I had during my brief adventure while looking up getopts command online.

Background

Traditionally when you need to pass parameters to a shell script you had to manage the command line parameters yourself. If your script had optional parameters then you will have a big chunk of code just to check what options are passed and what is not. Typically any script/program has 3 types of command line parameters as mentioned below : 

  1. Option : These types of parameters govern behaviour of your program for example -verborse will indicate your script generate detailed debug information so user can look for any problems as two why script did not work as expected.

  2. Option with values : These types of parameters govern behaviour of script but will take an additional value that will expect your script to behave in cetain way for example -debug 4 may govern what level of debug messages your script needs to generate.

  3. Positional Parameter : These are the arguments on which script will work with will be usually filename(s) or directory list or any arbitary value which script expects to be provided.

Some of the above parameter types might be manditory or optional based on how your script needs to work. After deciding what parameter you need to document it and display it users if he enters invalid options or invalid arguments. The getopts command tries to address these problems providing a simplified and uniform approach for handling command line parameters.

getopts command

This section we will concentrate on core functionality of the command. The SYNOPSIS of command is given below.

getopts optstring name [arg]

getopts command takes two manditory arguments optstring and name, one optional argument arg.  The optstring argument governs what option script accepts, do they take parameter or not and mode of getopts command. The name argument is a shell variable which getopts writes to each time its invoked with option that its has read, getopts work likes a shift command with command line arguments. By default getopts reads shell command line arguments the arg allows you to override it if required.  The command also works in other shell than bash please refer respective documentation to know the difference on how it works.

getopts modes

The getopts work in two modes which is specified at begining of optstring argument. 

  1. Verbose This is the default mode in this mode error handling is completely done by getopts including display of error message incase of invalid argument passed to an option. 
  2. Silent If you prefix ':' (semi colon)  to optstring then getopts works in silent mode allowing your code to handle error condtions and display custom error messages incase of invalid argument passed to an option.

getopts variables

The getopts uses following variables to pass option arguments and report error to script. 

  1. OPTARG This variable is set to the argument for an option that was found by getopts. In Silent mode it contains option switch of an option for which argument is not passed allowing to display custom error message.
  2. OPTIND  This holds index to next argument to be processed,  this is how getopts keep tracks of its own status between invocations.  Its used to shift positional parameters(Input type) after processing all options. 
    Its initially set to 1, and needs to be reset, If you want to parse anything again.
  3. OPTERR OPTERR is bash shell specific variable and not supported by other shells. It indicates whether or not bash shell should display error messages generated by getopts builtin. The value is set to 1 on every shell startup, set it to 0 if you don't want to see unwanted messages.

Building optstring

The most important part of using getopts is to build optstring. The steps below mention process we need to go through.

Step1 Mode to be used

The first step to decide is whether we need to handle invalid options in script and display custom error messages, if yes then you need to start the string with ':' this tells getopts work in Silent mode.

Step2 Select option names to use

The getopts does not allows long names as options so you will have to select have to use a-z or A-Z allowing max of 52 option switches to be used as options for script. If option takes an argument then it should be immediatelt followed by a ':' .

For example if we want script to receive an input directory (i) which will override default used, want to operate in verbose (v) mode if user needs to see detaled log and display custom error messages to user if provided invalid option the optstring will look below.

:i:v

Using the script

Now that we have learn so much about getopts I decided to provide a very simple script as an example. It will take two command line option arg and any number of positional parametes and display it on console. The SYNOPSIS of script would look like this.

SimpleScript.sh [-i args] [-v] para1 para2

How it works

The getopts is used with while loop as it works like a shift command till all our options are processed.

SimpleScript.sh [-i args] [-v] para1 para2

The script written works in Silent mode and will display its error messages if arguments are not passed to an option which expects it and will terminate.  The script also displays error message and terminates when invalid option is provided. The termination behaviour is introduced to stop arguments processed wrong way as script is not receiving proper option.

So once all options are read and used then we go for positional parameter reading with help of OPTIND variable.

Points of Interest

While working with getopts, I taught what features we can add to it to make it better and listed them down below.

  1. Ability to handle long option POSIX style (--verb) .
  2. Display custom error message without having to use Silent mode.
  3. Allow to specify Option with values as numeric only.

Thinking about these features I was searching online on how best to use getopts, I found this article that turned out be having all the above listed feature a silver bullet for command line option handling. Unfortunately on different flavours of LINUX\UNIX I found that not all three are supported. In GNU Linux it provides 2nd and 3rd feature. In Ubantu only core feature was supported.  If anyone knows which OS supports all please share it with me.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)