Work the Shell - Parsing Command-Line Options with getopt
I've talked before about how I am a lazy shell script programmer. It might be because I'm simply not a full-time professional software developer, and I don't even administer my own servers anymore—I outsource the job to Wisconsin.
Regardless of how much I program nowadays though, I still find myself needing simple little applications—tiny programs that do one simple task well.
And, then there are the throwaway scripts that stick around, ultimately becoming a mainstay of one's toolkit, spreading out to cover multiple functions and mysteriously growing to 100 lines or more.
I have one of those in my toolkit, a script that originally was intended simply to figure out the dimensions of a graphic file and produce the proper height and width attributes for an HTML image tag.
Now the script scale.sh has grown to 133 lines and does a variety of different, albeit related tasks. No surprise, it's also grown to have a variety of command-line arguments, as shown here:
$ ./scale.sh
Usage: scale {args} factor [file or files]
-a use URL values for APparenting.com site
-b add 1px solid black border around image
-i use URL values for intuitive.com/blog site
-k KW add keywords KW to the ALT tags
-r use 'align=right' instead of <center>
-s produces succinct dimensional tags only
A factor 0.9 for 90% scaling, 0.75 for 75%, or max width in pixels.
A factor of '1' produces 100%.
Crack open the code, and you'll see my dirty little scripting secret—a very sloppy approach to parsing command-line options:
if [ "$1" = "-a" ] ; then baseurl="www.apparenting.com/Images/"; shift fi
I did warn you that I was a lazy programmer, right? This is a pretty classic way to parse and process command-line arguments, actually. Check the value of $1, and if it's a known flag, change a default variable or two, then use the shift command to move $2 → $1, $3 → $2 and so on, effectively deleting the processed flag from the command-line args.
The problem is, when you have more than one or two flags, this really doesn't work. I step through the command flags alphabetically in my script—for example, invoking the script as scale -r -a will fail. It'll process the -r flag but never see the -a and generate an error condition.
Fortunately, there's a very nice Linux command called getopt that lets you parse through your command flags in a far more sophisticated manner.
The getopt command first requires that you let it rearrange how your command flags are organized, then you use the set command to update all the positional variables. After that, you can step through the positional variables with a case statement.
The first step is:
args=`getopt FLAGS $*` set -- $args
where FLAGS should be the individual letters of known and accepted command flags. If a flag has an argument that goes with it (like -s 30), append a colon to it.
For my script, it looks like this:
args=`getopt abik:rs $*` set -- $args
To see what happens, I've added a bonus echo statement. Here's the result:
$ scale -abs -k fdsf 100 *png args = -a -b -s -k fdsf -- 100 blooeeh.png
As you can see, getopt separates out each and every command flag and adds a -- flag that indicates when the command flags end—simple, really!
Now that the args have been restructured, parsing is relatively easy, though it looks pretty complicated (warning, I've stripped out a few clauses for simplicity):
for i; do
case "$i" in
-a ) baseurl="www.apparenting.com/Images/"
shift ;;
-k ) keywords=" ($2)"
shift ; shift ;;
-s ) verbose=0
shift ;;
-- ) shift; break ;;
esac
done
Let's read this backward. At the -- option, the loop will exit due to the break. Until that's hit, the for loop will just keep iterating, stepping through all the flags specified. This is how the order of the flags becomes irrelevant.
Each time a flag is matched, the desired action is taken, variables are set and so on, then the shift command shows up again to move all the command flags down one (for example, $2 to $1, $3 to $2 and so on).
Shell script case statement matching lines are all in the form of:
regex ) actions ;;
Dave Taylor has been hacking shell scripts for over thirty years. Really. He's the author of the popular "Wicked Cool Shell Scripts" and can be found on Twitter as @DaveTaylor and more generally at www.DaveTaylorOnline.com.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- Designing Electronics with Linux
- New Products
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Dynamic DNS—an Object Lesson in Problem Solving
- Linux Systems Administrator
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- Using Salt Stack and Vagrant for Drupal Development
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




4 hours 37 min ago
5 hours 11 min ago
6 hours 10 min ago
7 hours 25 sec ago
11 hours 2 min ago
14 hours 49 min ago
14 hours 57 min ago
17 hours 12 min ago
19 hours 41 min ago
1 day 5 hours ago