Shell Programming

Posted by: Rea Maor In: Programming - Thursday, May 3rd, 2007

Well, who says you have to use a real programming language anyway? You can still use the simplest scripting language of them all – the one that came built into your own operating system! While it’s not a viable option for building a whole program, the shell scripting language is suitable for what we call “glue”, being the commands that run in the background calling larger parts of your program – or even performing helpful tasks all their own.

In DOS, you know these as .BAT scripts. In Mac and Unix, you know these as shell scripts. The most common non-Windows shell is Bash, the “Bourne-again Shell”, which is a pun on the developer’s name of Stephen Bourne.

Shell scripting is good for “one-line fix” problems. In addition, it can be used to expand to multi-line scripts, automating small tasks that would be repetitive and tedious. But best of all is when you can call various utility programs in an automated fashion. Then anything which can be called from a command line can also become part of your script – just like a library of functions in one of those fancy languages!

When it comes to DOS, there is one command list tutorial which outshines them all. This Wikipedia page gives an excellent listing of DOS commands, and in every case possible, the equivalent Unix (bash) command as well. (The cases where the Unix command is missing is because it’s for a DOS-specific function or it’s accomplished a different way in Unix.)

Unfortunately, DOS as it survives today has been mostly left aside by Microsoft. And in any case, DOS has a mere fraction of the functionality of Bash and other Unix shells. If you skim the commands of the DOS Wiki link, you’ll note that there’s no control structures like “if”, “for”, and “while”. Bash gives you all this, and more.

Windows users can get Bash here. Bash won’t be quite as graceful on Windows, but you can manage for the most part. New Mac users can follow right along – Bash is the default shell running in the new Mac terminals! Old Mac users can try to follow along in tcsh (as I understand it, they’re quite similar), or check this link at O’Reilly on how to make the transition.

And BSD, Linux, Solaris, and other Unix flavors can dive right in – you’ve probably danced many of these steps before!

Now that we’re all using the same (almost!) shell, lets take a bash at Bash!

Comments:


#
# This is a comment!
#

Just start a line with a pound sign. The exception is the first line of the script, which will be something like:


#!/bin/bash

That tells it (the operating system) what program to use (the system shell). So a comment is a pound sign and anything but an exclamation point.

Data Declarations:


FILE="my_homework"
temperature=85
COLOR_PALETTE="yellow"$MYCOLORS"red"

That last one looks crazy, but that’s how you concatenate (fasten together) strings in Bash. Now, here’s a point that will bite you many times: When you assign a variable in Bash, you just type the name. When you recall a variable later, you precede it with a dollar sign, like this:


echo $FILE
echo $temperature > TempRecord.txt
COLOR_PALETTE="yellow"$MYCOLORS"red"

Output statement:


echo "Hello World!"
echo $UID

Input statement:


read VARIABLE

This is just like the INPUT command in BASIC (which we’re not going to visit… it’s bad enough I subjected you to Lisp last time). The read command waits for typed input and sticks it into the designated variable. Example at the bash% prompt:


bash% read TEST
this is a test
bash% echo $TEST
this is a test

I typed in the top line, then had it echoed back.

Math:


echo $((8*8))
TEST=$((64/2))
GROSS_WEIGHT=$(($WEIGHT+10))

The $((…)) part tells it to execute the math problem.

File access:

There are several ways. To print to a file:


cat "some text" > myFile.txt

…is equivalent to “write” mode. It will either create “myFile.txt” if it’s new, or replace myFile.txt if it existed already. This command:


cat "some text" >> myFile.txt

Will append the text to what was already in the file, adding it at the end. To print out a file:


cat myFile.txt

…will dump it to the screen. “cat” is a Unix file utility. Dozens of other file utilities are possible, but you need the Unix environment tools for them. Cygwin or the unix-utils collection will be the answer for Windows users.

Conditional statements:


if [ "$answer" != "Lebanon" ]; then
echo "I'm sorry, that is incorrect!"
fi

Here’s another kink: “fi” is the delimiter to end the conditional block in Bash. This is actually a sort-of standard that somebody came up with. You also end a “case” conditional with “esac”. However, you end a “do” block with “done”. This is one case where it seems they really were trying to mess with people.

Fixed iteration:


for FILE in $(ls ./*.jpg); do
mv $FILE ~/archive/
done

This is actually the kind of cool way they do it in Perl and Python; the “ls” command will list the files in the current directory, and then the “for” block repeats the command for each listing. This has proved one of the most valuable tools for file slinging, such as renaming, moving, deleting, and other kinds of operating on selected groups of files. You can also put any command inside of $(…). This command alone can knock an all-day tedious task down to a few minutes. Here’s another example:


for NUMBER in $(seq 1 10); do
echo $NUMBER "count"
done

This will loop from 1 to 10.

Conditional iteration:


LOOPVAL=$((10))
while [ "$LOOPVAL" -gt "0" ];
do
....
LOOPVAL=$(($LOOPVAL-1))
done

Libraries:

No “libraries” of code per se in Bash. However, you can always call another script or program from a script. For instance, many Unix users have a few files such as “.bash_profile” in their home directory, where things like the format of the prompt is set with a variable. Command aliases and functions can also be defined in one file and called from another.

But really, shell programming isn’t intended for that kind of scale.

Functions:


check_letters() {
lettertest $getword $answer
if [ "$?" != 0 ]; then
check=0
else
check=1
fi
}

The above block defines a function! You would call it later in the script with:

check_letters

There’s much more to shell scripting, of course. It can be a powerful tool for the end user and is an especially necessary tool for the system administrator! This Wiki article lists some more Bash magic.

Bash has a syntax that tastes a lot like Perl. Perl, in fact actually borrows features from a variety of other languages including C, Bash, Awk, sed and Lisp! It was originally intended as a “meta-shell” language, uniting all the little features of the other smaller languages.

We will be covering some more of the languages Perl borrows from, but not Perl itself, because the whole Perl language is just too big to cover in the scope of our project. But our next language will be very interesting, particularly for those who want a GUI program (running in a dialog, with buttons and everything!) to be as easy as scripting a command-line interface.


Related Posts:


2 Responses to “Shell Programming”

  1. webjourneyman Says:

    Would you mind giving the skinny on PHP? That’s the programming language I’ll be needing to take a look at if/when I need to customize drupal.

  2. Rea Maor Says:

    Ye sure, i would love to.
    i have actually planed this to be 12 parts series about programming,
    php should be very soon…

Leave a Reply