A Simple Shell Program


The first rite of passage for any aspiring programmer is to write the classic "Hello World!" program. Here is one way to write it in the Bourne shell programming language. Enter the text shown in Listing 10.1 into your favorite text editor (the line numbers in this code are for reference only; don't include them when you enter the code).

Listing 10.1. A Basic Shell Program

1.  #!/bin/sh 2. 3.  # The legendary Hello World program 4.  # As implemented in the Bourne shell programming language. 5. 6.  echo 7.  echo "Hello World!" 8.  echo 9.  exit 0

Save this program as a file called hello. (Remember, in UNIX the filename extension doesn't matter and is not required.) Next, you need to make the file executable. You can do this with the following command:

# chmod u+x hello


This command gives the owner of the file permission to execute it. If you're concerned about security, you might want to use the following command instead:

# chmod 700 hello


This ensures that only you can access the file in any way, and other users can't even read it. See Chapter 13, "Users, Groups, and Permissions," for more information.

Tip

Traditionally, shell scripts have the extension .sh so that anyone can quickly tell in a directory listing that a certain file is a shell script. The extension is not necessary, however, and in some cases you might want to leave it out to make the commands easier to type (you can't just omit the extension as with .exe files in DOS). If you're writing a shell script for end users who have no knowledge of what the .sh extension means, you can safely leave the extension off, as in this example.


Next, execute the file. The following sequence shows the command you type as well as the output of the program:

# ./hello Hello World!


Note

You have to prefix the name of the command with ./, indicating that the command is a program located in the current directory (.) rather than in one of the locations specified in your path, such as /usr/local/bin. It's possible to add the current directory (.) to your path as described in Chapter 9, "Customizing the Shell," but it's not a particularly good idea, especially as rootyou don't want to make it too easy to accidentally execute any old program you have lying around. They might not all be safe to run as root, after all!


Note

Because shell scripts are interpreted, you don't necessarily have to make them executable in order to run them, or even have the interpreter line at the top. If you prefer, although this method is less conveniently "encapsulated" than the previous method, you can run the script as an argument to /bin/sh itself. This way you can run the program even if the script is not set executable or does not contain the interpreter line:

# sh hello



Understanding the Shell Script, Line by Line

Now let's look at the lines in the sample shell program in detail and see what each one does:

  • Line 1 This line contains the magic character sequence #!, which tells the executing shell that what follows is a script that should be interpreted by the program named after #!. In this case, it tells FreeBSD that it should use the Bourne shell interpreter /bin/sh to interpret the remainder of the script. If this were a Perl script, you would use /usr/local/bin/perl. For a Python script, you would use /usr/local/bin/python, and so on.

  • Lines 2 and 5 These are simply blank lines. The shell ignores whitespace unless it is quoted (more on that later). It is a good idea to use whitespace to make your program more readable.

  • Lines 3 and 4 These are comments. Comments are lines in a shell program that begin with a # character and are entirely ignored by the interpreter. They are used for the benefit of the programmer who needs to revisit a complicated program he wrote six months ago and try to figure out what it does again, or for another user who needs to know how certain parts of the code operate.

  • Line 6 The echo command takes whatever data it receives as an argument and echoes it to STDOUT ("standard output", which is normally the screen). This output can be redirected, however, so that echo sends the output somewhere else, such as to a file. In this case, echo by itself simply prints a blank line on STDOUT, making the script's output more readable.

  • Line 7 The echo command here prints the string Hello World! to STDOUT. The quotes tell the interpreter that everything inside them should be interpreted as a single argument (that is, the shell should interpret the string as one long parameter instead of many separate parameters separated by spaces). Without the quotes, the shell will interpret the whitespace as an argument separator. In this case, the quotes would not have been strictly necessary, but you will see later on in the chapter why quoting is important. It's a good idea to get into the habit of quoting strings such as these.

  • Line 8 The echo command here prints a blank line again.

  • Line 9 The exit command exits the program and returns an exit status to the invoking program. (This is normally your login shell, but it could be another program, such as another shell script, possibly being called automatically at a scheduled time.) An exit status of 0 indicates that the program terminated normally. An exit status of anything other than 0 indicates that an error occurred. You have the option of specifying any exit code you want (at any time in the program) so as to communicate various runtime conditions to the invoking shell, which then determines what action it should take next based on the success or failure of your shell script.

In a program this short, setting the exit status isn't really necessary. If the exit status is not implicitly set, the exit status returned will be the exit status of the last command that was run in the script. It is best to be aware of the exit status, though, because it will become important as you start to write larger and more complex shell programs. Later in this chapter, you will see how the exit status of a command can be used in a shell script to make automatic decisions about the next action that should be performed. However, setting the exit status should not generally be necessary; if a script is written properly, it will exit with a status of 0 on its own. Otherwise, it will have inherited an error condition from one of its lines, and you as the programmer should address this rather than masking the true status with an exit statement.

Using the printf Command

The previous program could also have been written using printf commands instead of echo. The printf command performs a similar function, but it allows far more control over how its output is formatted. The example in Listing 10.2 shows how the program could be rewritten using printf instead of echo.

Listing 10.2. Using printf Instead of echo

1.   #!/bin/sh 2. 3.  # The legendary Hello World program 4.  # As implemented in the Bourne shell programming language. 5. 6.  printf "\nHello World!\n\n!"

If this program is run, the output it produces will look exactly the same as the previous program's. This, however, is only where the demonstration of printf begins.

If you have ever programmed in C or Perl before, the syntax of the printf command will look familiar to you. The backslash (\) is an escape character that normally indicates that the character immediately following it should be interpreted literally (as with quotation marks or spaces), but in certain combinations it takes on entirely different special meanings. In this case, \n is a newline character. This is why you could eliminate the two echo commands that inserted blank lines when you use printf, because now you can embed the newlines directly into the string you want to print. At the end of the string, you used two newline characters because printf does not automatically insert a newline at the end of a printed string; thus you want two newlines to get a blank line in your output. Here's an example in which printf doesn't automatically insert a blank line at the end:

printf "Hello " printf "World!\n\n"


These two lines in a shell script would produce the output "Hello World!", even though they are given as separate statements. This is because printf does not automatically output a newline (which in UNIX implies a carriage return) at the end of a statement, the way echo does. If you had used echo in the previous two lines instead of printf, "Hello" and "World!" would appear on separate lines. This gives some indication of how much more control printf gives you over your program's output than echo; you have to be more explicit about what you tell it, but it can be configured with far more flexibility.

The printf command supports the formatting characters outlined in Table 10.1.

Table 10.1. Formatting Control Characters from printf

Formatting Characters

Description

\a

Rings the terminal's bell. In the old teletype days, this rang an actual bell on the teletype machine. These days, it usually beeps the computer's speaker.

\b

Prints a backspace character.

\f

Prints a form-feed character (the screen is cleared, or in printed output, the current sheet is ejected and a new one loaded).

\r

Prints a carriage return (the cursor returns to the beginning of the line but does not move down to the next line). The result is that the previous output on the line will be overwritten by whatever comes after \r.

\n

Prints a newline character (which moves the cursor to the beginning of the next line).

\t

Prints a tab character.

\v

Prints a vertical tab character, which is equivalent to a linefeed without a carriage return.

\'

Prints a single-quote character.

\"

Prints a double-quote character.

\\

Prints a backslash.

\num

Prints the ASCII value of the octal 1-, 2-, or 3-bit value num. You will probably never need to use this option in a shell program.


Of course, simply being able to echo prewritten messages to the screen is not very useful. You need the program to be able to give you different output depending on what data it has received. This is where variables come in.




FreeBSD 6 Unleashed
FreeBSD 6 Unleashed
ISBN: 0672328755
EAN: 2147483647
Year: 2006
Pages: 355
Authors: Brian Tiemann

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net