TweetFollow Us on Twitter

Back to bash Basics: Part 2 Time to Advance Ourselves

Volume Number: 21 (2005)
Issue Number: 11
Column Tag: Programming

Mac In The Shell

Back to bash Basics: Part 2 Time to Advance Ourselves

by Edward Marczak

With any exercise, you need to continually push yourself. Without that extra effort, what once was a challenge becomes easy, something to drift through. At the same time, you may be missing advanced techniques that make other areas easier or more efficient. Similarly, shell scripting can go many layers deep, and you can exercise your knowledge in many ways. Last month in, "Back to bash Basics Part 1," we focused on flow control. You may have noticed some of the things I didn't cover explicitly. There's always more to learn! Let's tie up those loose ends.

More Looping

Since we discussed looping constructs so much last month, that's where we'll pick up. In the select example, you'll see a break statement - that could use some explanation. break simply terminates the current loop. If it were removed from the select example, you would be asked repeatedly which file you want to inspect. Let's see what that would look like:

#!/bin/bash

select theItem; do
        if [ $theItem ]; then
                file $theItem
        fi
done

When this is run, the output looks like this:

Jack-Kerouak:~/bin marczak$ ./st.sh *
1) BidToJob.dmg 
2) bomcheck.sh
3) cl.txt
4) createdmg
5) diskrep.sh
6) exscript
#? 3
cl.txt: ASCII text
#? 4
createdmg: ASCII text
#? 5
diskrep.sh: Bourne-Again shell script text executable
#? ^C

Notice that this time, we need to press ctrl-c to stop the program. break applies to any loop:

#!/bin/bash
for i in $*;
        do
        if [ ! -O $i ]; then
                echo You do not own $i!  I am outta here!
                break
        fi
        echo $i is your file!
done

Running as me, I'm shown:

$ ./bt.sh *
BidToJob.dmg is your file!
bomcheck.sh is your file!
bt.sh is your file!
cl.txt is your file!
[...clipped for brevity]

Running in that same directory as root gives us:

# ./bt.sh *
You do not own BidToJob.dmg! I am outta here!

AOT (or, how the shell will separate files)

Have you ever crossed your AOT (Acronym Overload Threshold)? "There's a problem with the RIP!" Raster Image Processor, or Routing Information Protocol? While there's only so many TLAs (Three Letter Acronyms) that you can deal with, I need you add one more: IFS (no, not Iterative Fractal Systems!). The shell uses the Internal Field Separator to determine how to break apart tokens, and how to separate incoming parameters. By default, IFS is equal to space, tab and newline.

When we discussed the for loop last month, several things were quickly touched upon that can be expanded. In addition to the $@ variable, which expands to individual double-quoted strings, there is the $* variable, which is a single string containing each positional parameter. How do you know where each parameter breaks? $* separates each parameter by using the first character of your IFS variable. We'll get back to how this can be very useful.

Also, last month showed an example that looked something like this:

FILES=`ls *.sh`

for i in $FILES
do
        ...
done

This example 'just works' because ls *.sh will separate its output with linefeeds. Hey, that's one of the characters in IFS by default! What good fortune! This same example will fall apart if you reassign the IFS variable prior to the loop:

IFS="-"
FILES=`ls *.sh`
for i in $FILES; do
...
done

$i will still hold $FILES, but it won't be tokenized - not the way you'd expect (the line feeds will still be in there, but $i won't break on them).

So, then, why would we ever touch IFS? Well, what if you wanted to search through something that is not broken up by a space, newline or tab? Like $PATH, for instance:

#!/bin/bash

IFS=:

for theDir in $PATH
do
        theLatest=`ls -lotr $theDir | tail -1`
        echo Newest file in $theDir:
        echo $theLatest
        echo
done

This simply goes through our $PATH and tells us the newest file in each directory. Could be useful.

Oh, and another thing

Like Apple, shell scripting always seems to have "one more thing." For this month, this thing comes in the form of being able to effectively handle parameters. Time to introduce shift and getopts.

When writing a script, parameters can be accessed a few ways. If you always rely on direct access ($1, $2...etc), you run into some limits. One way to simply loop through all parameters is to use shift. shift makes $1 = $2, $2 = $3...etc. You lose the first value that was assigned to $1. To look for a few specific parameters, you can loop through the values:

#!/bin/bash

while [ `echo $1 | grep "-"` ]; do
        case $1 in
                -a ) echo "You supplied the -a flag";;
                -b ) echo "You supplied the -b flag";;
                -c ) echo "You supplied the -c flag";;
                * ) echo "Usage: $0 -a -b -c";
                exit 1;;
        esac    
        shift
done

Run this code and you'll see:

$ ./shifttest.sh -b -a
You supplied the -b flag
You supplied the -a flag

Now, shift is cool, and still comes in handy, but to truly handle command-line options smoothly, we have to employ getopts. Sure, you can roll your own each time, however, people have come to expect their options to behave in certain ways. One should be able to combine options, as with tar, for example: tar -xzvf blah.tar.gz. Basically, you don't need to roll your own because getopts exists.

getopts allows you to handle options in a standard way. Seeing it in action is the quickest way to get up to speed:

#!/bin/bash

while getopts ":xyz:t" theOption; do
        case $theOption in
                x ) echo "Option x chosen";;
                y ) echo "Option $theOption chosen";;
                z ) echo "Option z chosen with argument: $OPTARG";;
                t ) echo "Option t chosen";;
                \? ) echo "Unknown option chosen"
                        exit 1;;
                * ) echo "You need to supply an option!"
                        exit 2;;
        esac
done

getopts is designed to be dumped in a loop that will feed it arguments passed into the script. It accepts a string that defines the allowed options, followed by a variable that will hold the current option, sans the "-" or "+" (nicely, either are allowed). Using getopts will define two variables: $OPTIND, the current index and $OPTARG, the current argument passed with an option. Running this produces this output:

$ ./gotest.sh -yxz test
Option y chosen
Option x chosen
Option z chosen with argument: test

The string that getopts accepts can only contain letters and the colon character. Each letter is an option you wish to support. If a letter is followed by a colon, that tells getopts that an argument is required. By having a lead colon character in the parameter list string, you suppress the error message that getopts will print if an option is not recognized. In either case, an unrecognized option will set the variable to "?", so you can deal with it.

Put it all Together

I've gotten a request or two asking how to deal with math in the shell. While there are specialized CLI apps that will deal with arithmetic, the shell can do some basic functions, and sometimes, that's all you need. The trick is the underused declare statement. declare tells the shell how you want to treat variables, which are strings by default. So, this doesn't do what one would expect:

$ number1=7
$ number2=8
$ total=number1*number2

When you echo $total, you get "number1*number2": strings. We need to tell the shell that $total should be treated as an integer:

$ declare -i total
$ total=number1*number2
$ echo $total
56

Much better! declare can define several different types of variables:

-a   variable is an array
-i   treat as integer
-r   makes variable read-only
-x   automatic export (like the 'export' built-in)

There are some others, but this is all we need concentrate on for now. All of the usual suspects are available as mathematic operators:

+   Addition
-   Subtraction
*   Multiply
/   Divide
%   Remainder
<<  Bit-shift left
>>  Bit-shift right
&   Bitwise and
|   Bitwise or
~   Bitwise not
!   Bitwise not
^   Xor

In addition to declare-ing a variable to be an integer, you can use let to make the assignment:

let theTotal='5 * 7'

Ah, let....brings me back to my C64 BASIC days...

Now, you should be able to write fairly sophisticated shell script that includes slick input processing, good error handling and even some basic computations!

Make Yourself Useful...

...to everyone. Just remember that bash scripting will help you not only with OS X, but with Linux, IRIX, FreeBSD, and even Windows - if you install a Unix shell there (which can be had for free from Cygwin or Microsoft).

This month highlights the fact that shell scripting is relatively easy, can be fun and powerful. Even better, you'll find bash built-in to every OS X machine you touch! Let this all sink in: while I'll get back to bash scripting in future columns, more Unix detours next month!


Ed Marczak keeps it simple. Tech simplicity at http://www.radiotope.com

 
AAPL
$100.58
Apple Inc.
+0.01
MSFT
$45.22
Microsoft Corpora
+0.27
GOOG
$583.37
Google Inc.
-1.12

MacTech Search:
Community Search:

Software Updates via MacUpdate

Pages 5.2.2 - Apple's word processo...
Apple Pages is a powerful word processor that gives you everything you need to create documents that look beautiful. And read beautifully. It lets you work seamlessly between Mac and iOS devices. And... Read more
Quicken 2015 2.0.1 - Complete personal f...
The new Quicken 2015 helps you manage all your personal finances in one place, so you can see where you're spending and where you can save. Quicken automatically categorizes your financial... Read more
CleanMyMac 2.2.7 - Delete files that was...
CleanMyMac makes space for the things you love. Sporting a range of ingenious new features, CleanMyMac 2 lets you safely and intelligently scan and clean your entire system, delete large, unused... Read more
MacFamilyTree 7.2.4 - Create and explore...
MacFamilyTree gives genealogy a facelift: it's modern, interactive, incredibly fast, and easy to use. We're convinced that generations of chroniclers would have loved to trade in their genealogy... Read more
Videobox 4.1.1 - Download Flash video th...
Videobox allows you to quickly and easily download Flash video from most all of the popular video sites on the internet. Videobox will convert the video into a native Quicktime format so it's ready... Read more
Web Snapper 3.3.5 - Capture entire Web p...
Web Snapper lets you capture Web pages exactly as they appear in your browser. You can send them to a file as images or vector-based, multi-page PDFs. It captures the whole Web page - eliminating... Read more
Picasa 3.9.138 - Organize, edit, and sha...
Picasa and Picasa Web Albums allows you to organize, edit, and upload your photos to the Web from your computer in quick, simple steps. Arrange your photos into folders and albums and erase their... Read more
Tidy Up 3.0.15.0 - Find duplicate files...
Tidy Up is a complete duplicate finder and disk-tidiness utility. With Tidy Up you can search for duplicate files and packages by the owner application, content, type, creator, extension, time... Read more
Parallels Desktop 10.0 - Run Windows app...
Parallels Desktop is simply the world's bestselling, top-rated, and most trusted solution for running Windows applications on your Mac. With Parallels Desktop for Mac, you can seamlessly run both... Read more
Apple Final Cut Pro X 10.1.3 - Professio...
Apple Final Cut Pro X is a professional video editing solution.Completely redesigned from the ground up, Final Cut Pro adds extraordinary speed, quality, and flexibility to every part of the post-... Read more

Latest Forum Discussions

See All

DotEmu Summer Sale Cuts Several Games’ P...
DotEmu Summer Sale Cuts Several Games’ Prices to $0.99 Posted by Ellis Spice on August 21st, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
King Announces its Newest “Saga” – Diamo...
King Announces its Newest “Saga” – Diamond Digger Saga Posted by Jessica Fisher on August 21st, 2014 [ permalink ] Diamond Digger Saga, by King Digital Entertainment, promises to be another addictive, adorable game in the “Saga” | Read more »
Spacetime Studios’ Greg Mueller Tells Al...
| Read more »
TourStar Review
TourStar Review By Rob Thomas on August 21st, 2014 Our Rating: :: BORING TOURINGUniversal App - Designed for iPhone and iPad When The Ramones sang “Touring, touring/It’s never boring,” they clearly weren’t referring to TourStar.... | Read more »
Track Your Pregnancy with Glow Nurture
Track Your Pregnancy with Glow Nurture Posted by Jessica Fisher on August 21st, 2014 [ permalink ] iPhone App - Designed for the iPhone, compatible with the iPad | Read more »
Outcast Odyssey – An Interview with the...
At this year’s San Diego Comic-Con, fans got the chance to meet and mingle with several of the artists behind Magic Pixel Games and Namco Bandai’s upcoming card battler, Outcast Odyssey. Considering many of these artists have worked on comics in the... | Read more »
BoxPop Review
BoxPop Review By Jennifer Allen on August 21st, 2014 Our Rating: :: UNTAXING PUZZLESUniversal App - Designed for iPhone and iPad Move from tile to tile to clear the board in this slightly too simple and easy puzzle game.   | Read more »
Breakdown Buddy Review
Breakdown Buddy Review By Jennifer Allen on August 21st, 2014 Our Rating: :: FLAWED CONCEPTiPhone App - Designed for the iPhone, compatible with the iPad There’s a good idea here, but Breakdown Buddy isn’t as useful as it tries to... | Read more »
jamstik, the Guitar You Can Take Everywh...
jamstik, the Guitar You Can Take Everywhere, is Now Available for Purchase Posted by Jessica Fisher on August 21st, 2014 [ permalink ] Zivix has announced that their guitar-in-your-pocket, | Read more »
Star Walk 2 - Guide to the Sky Day and N...
Star Walk 2 - Guide to the Sky Day and Night 1.0.0 Device: iOS Universal Category: Education Price: $2.99, Version: 1.0.0 (iTunes) Description: The next generation of the best-selling Star Walk, winner of Apple Design Award, used by... | Read more »

Price Scanner via MacPrices.net

21-inch iMacs on sale for up to $150 off MSRP
B&H Photo has 21″ iMacs on sale for up to $150 off MSRP including free shipping plus NY sales tax only. B&H will also include a free copy of Parallels Desktop software: - 21″ 2.7GHz iMac: $... Read more
27-inch 3.2GHz iMac on sale for $1698, save $...
Abt has the 27″ 3.2GHz iMac on sale for $1698 including free shipping. Their price is $101 off MSRP. Read more
Mac Backup Guru 2.0 Drive Backup/Cloneing Uti...
Mac Backup Guru developer MacDaddy has released Mac Backup Guru 2.0, offering new and enhanced advanced features, such as bootable backups, synchronised volumes and folders, and a Snapshot mode that... Read more
Operate GE’s New Free-Standing KItchen Range...
Think you accidentally left the oven on? Switch it off while on the go. The new free-standing Profile™ Series gas and electric ranges are GE’s second cooking appliances, following their wall oven, to... Read more
Parallels Announces Parallels Desktop 10 for...
The no. 1-selling software for running Windows applications on a Mac becomes an even easier choice for millions of consumers and IT professionals worldwide with the launch of the most powerful... Read more
Apple now offering certified refurbished 2014...
 The Apple Store is now offering Apple Certified Refurbished 2014 MacBook Airs for up to $180 off the cost of new models. An Apple one-year warranty is included with each MacBook, and shipping is... Read more
Best Buy’s College Student Deals: $100 off Ma...
Take an additional $100 off all MacBooks and iMacs, $50 off iPad Airs and iPad minis, at Best Buy Online with their College Students Deals Savings, valid through September 6th. Anyone with a valid .... Read more
MacBook Airs on sale for $100 off MSRP, free...
B&H Photo has three 2014 MacBook Airs on sale for $100 off MSRP. Shipping is free, and B&H charges NY sales tax only. They also include free copies of Parallels Desktop and LoJack for Laptops... Read more
Razer Taipan Mouse For Gamers And Non-Gamers...
If you’re a serious gamer on either Mac or Windows PCs, a serious gaming mouse is a necessity for first-tier performance. However, even if like me you’re not much of a gamer, there’s still a strong... Read more
15-inch 2.2GHz MacBook Pro on sale for $1899,...
Adorama has the new 15″ 2.2GHz Retina MacBook Pro on sale for $1899 including free shipping plus NY & NJ sales tax only. Their price is $100 off MSRP, and it’s the lowest price available for this... Read more

Jobs Board

*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Position Opening at *Apple* - Apple (United...
**Job Summary** As more and more people discover Apple , they visit our stores seeking ways to incorporate our products into their lives. It's your job, as a Store Read more
Position Opening at *Apple* - Apple (United...
…Summary** As a Specialist, you help create the energy and excitement around Apple products, providing the right solutions and getting products into customers' hands. You Read more
Project Manager, *Apple* Financial Services...
**Job Summary** Apple Financial Services (AFS) offers consumers, businesses and educational institutions ways to finance Apple purchases. We work with national and Read more
*Apple* Solutions Consultant (ASC)- Retail S...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.