Shell scripts

Shell scripts

Another thing good to know is how to write shell scripts. They are commonly used in the setup and in the automation of system tasks. In DOS and similar OS's there are a simple shell script in the batch files, with .BAT filename extension. The writing of Linux shell script is similar, with some enhancements.

Type in a test script

To begin, type in the following with your favourite editor, and save it with filename "first" in your home directory.

#!/bin/sh
# This is a comment
# The first script I've ever created.
echo -n "My first script runs at "
date

Make the script run.

To make Linux understand it's a shell script, do a chmod on the file. Do a chmod 755 first at your prompt (if you don't understand what that means, go read the the Section called Dealing with user rights in the filesystem.). If you have colour support in your ls, the file will have another colour.

Now type first and watch the output. It should say something like this:

My first script runs at Sun Feb 15 02:33:35 CET 1998
(Of course it should give you the correct date. If you don't have the correct date, use xntpd. Read the Section called xntpd.

Well, actually it's lying, since this isn't my first script, not at all :-)

What did we do ?

Now let's check out what the cute little script did...

Beginning of file

A shell script always starts with something like this:

#!/bin/sh
Telling your shell what program to execute to parse the script. /bin/sh should be availiable on most Linux/UNIX systems, on my system a symbolic link to /bin/bash.

Comments

Lines beginning with '#' are considered comments. Always comment your scripts, otherwise you won't remember after a month why you did things that way. Try to keep version information and date of last modification there too.

Commands

In the shell script you can use commands just like you would type them in at your prompt. Two examples of that are in the example script, echo and date they are both examples of small unix programs doing their specific tasks very well.

echo

echo does what it's named.. echoing something to the screen. If you give it the -n variable (as in the example script) it won't put any newline after it's output. There are few other parameters, check out the man page.

date

Prints the current system time and date.

if, for, case

Bash of course has support for these..

if

This is one of the most useful commands, when you want to check if a file is where it should be, if a command executed successfully, and whatever else you usually use a if command for. Type in the following example in second and chmod 755 it.

#!/bin/sh

ping -c 2 localhost
if [ $? != 0 ] ; then
    echo "Couldn't ping localhost, weird"
    fi

ping -c 2 veryweirdhostname.noend 
if [ $? != 0 ] ; then
    echo "Surprise, Couldn't ping a very weird hostname.."
    fi

echo "The pid of this process is $$"
(Yes, I do believe a lot in examples :) ) OK, let's check out what we're doing. ping is a net command that checks if a host is up and running, and how long time it takes for a packet to travel the way to the host. If it finds the host and succeeds pinging it, it will leave an errorlevel of 0, else it will leave another, higher errorlevel. That's common practice, if something goes well, it usually leaves errorlevel 0, else it gives something else.

for

For is useful when you want to do something on every file in a directory, the following will do a file on every file with a .sgml extension in the current directory. file is a very useful command trying to determine what type a file is.

#!/bin/bash
for sgmlfile in *.sgml ; do
    file $sgmlfile
    done
I'm sure you can find a better example, please mail it :)

case

Case is very useful when you want to give your shell scripts commandline parameters. Almost all scripts in the SysV init dirs has start, stop and perhaps restart as possible parameters. That's done this way;

#!/bin/sh

case "$1" in
    start)
    echo "Parameter was start"
    ;;

    stop)
    echo "Parameter was stop"
    ;;
    
    reload)
    echo "Parameter was reload"
    ;;
    
    *)
    echo "Usage: `basename $0` {start|stop|reload}"
    ;;
    esac
This example also shows how to include a command in a string, very useful feature of UNIX. Put a command inside two "`" and it's output will be inserted. In this case, basename $0 removes any directories from the name of the script. So if the script is named /scripts/third, it won't say "/scripts/third {start|stop|reload}" but "third {start|stop|reload}".

Linux scripting is wonderful, if you compare with DOS or Windows NT or something similar. There are other more powerful scripting languages than bash's, for example perl and python, I don't know too much about either of them, but as fast as I do, I'll write a small chapter.