Project75.Use Functions in Scripts


Project 75. Use Functions in Scripts

"How do I avoid repeating the same piece of code in a shell script?"

This project demonstrates the use of Bash functions in shell scripts. It shows you how to use functions as a way of gathering commonly used code into blocks and demonstrates some handy tricks you can employ in your own code.

Learn More

If you're not familiar with Bash functions, refer to Project 52.


Functions' Power, Multiplied

In Project 52, we covered the technique of combining command sequences into functions that can be invoked from the command line. Within Bash scripts, functions work much the same way that functions do in other languages, such as JavaScript and C.

When functions are incorporated into a script, they usually are grouped at the top of the file, ahead of the main body of the code. When the script is invoked, Bash reads and parses the functions, which makes them available for use within the actual script. (Functions are not executed when they are parsedonly when they are called by the script.)

Tip

Access an argument passed to a shell script from within a function by passing the argument to the function. To access the script's $2 from within function usage, for example, call usage as follows:

usage "$2" other params...


Within usage, the value of the main script's $2 can be accessed through the function's $1.


Like shell scripts, functions accept arguments, and both use the same syntax to refer to arguments. The first argument passed to a script or function is available in the variable $1; the second, in $2, and the nth, in variable $n. Bash also provides two special variables: $* expands to a list of all arguments, and $# expands to the total number of arguments passed.

Because of their shared syntax, arguments passed to a script are not accessible directly by the functions within it, but are available again when a function terminates and the main body of the script executes.

One point to be aware of: The variable $0 represents the script name in both the script and its functions. Use the special variable $FUNCNAME to access the name of the current function.

Write a Function

Most nontrivial shell scripts take arguments, and a well-written script will perform some validation on the arguments it receives. Validation methods can vary widely, depending on the nature of the arguments involved (testing for numbers versus text, for example), but most Unix commands and scripts respond the same way when incorrect arguments are passed: by writing a usage line to the terminal. In a script that does a lot of validation, handling this kind of repetitive task is an ideal candidate for a function.

Suppose that we are writing a script that does a lot of validation. We might write a simple function to be called from the many points of validation in our hypothetical script. The function would display usage information in the terminal window. Our example function, appropriately called usage, has been taken from a real-world script that creates a new Unix group.

usage () {   echo "Create a new group"   echo " Usage: ${0##*/} groupname gid"   if [ "$*" != "" ]; then echo " Error: $*"; fi   exit }


Tip

A usage line traditionally displays the name of the script. Use the special variable $0 instead of writing the script name literally. In this way, the name that's displayed always reflects that of the script, even if the script is renamed after it's written. The special variable expansion ${0##*/} truncates the leading pathname from the script name. If the script is called by a command line such as /usr/local/bin/my-script, the variable expansion becomes my-script.

Project 76 covers Bash parameter expansion.


In the new-group script, usage displays an informational message and a usage line, and (optionally) an error message preceded by the text Error:. Because this function is called in response to fatal errors, it also shuts down, or exits, the script. A function that simply completes and returns to the main body of the script should not finish on exit: An exit statement terminates the entire script.

Let's use our function to report an error when the number of arguments passed to a script is not two. Our script calls the usage function if the wrong number of arguments is passed.

if [ $# -ne 2 ]; then   usage fi


To pass an error message to the function, call it like this.

if [ $# -ne 2 ]; then   usage "Two arguments expected but $# received" fi


Learn More

Projects 9 and 10 show you how to write simple Bash shell scripts.


Unix commands usually write error messages to standard error instead of standard output. We can change our usage function to honor this convention by using a redirection trick. Normally, the echo command writes to standard output, but if we merge standard output into standard error by using the notation 1>&2, or the equivalent >&2, all output will be sent to standard error instead. As an example:

echo " Usage: ${0##*/} groupname gid" 1>&2


Learn More

Project 6 covers the concepts of redirection, standard output, and standard error.


Underline a String

Here's a handy function to underline a line of text. It accepts a line of text as a single argument, displays the text on a line, and places a line of dashes equal in length to the text on the line below it.

# Function Underline(string-to-underline) # Display and underline a string. # $1: the string to underline Underline () {   local -i len # to hold the length of the string   # write out the string and a '-' for each charater   len=${#1}; echo "$1"   while ((len!=0)); do echo -n "-"; len=len-1; done; echo   return 0 }


Tip

An often-used convention names functions starting with a capital letter, helping distinguish functions from variables and commands.


Our function, named Underline, assigns the number of characters in parameter 1 to the variable len by using the special notation ${#1}. It then displays the text held in parameter 1 and loops to display the appropriate number of dashes below the text. We employ a few more tricks besides ${#1}. Passing option -n to echo stops it from displaying each dash on a new line. Also, we declare len to be a local integer variable in the line

local -i len # to hold the length of the string


A local variable exists only while its defining function executes and prevents us from accidentally overwriting a variable of the same name from the main script. The option -i makes len an integer variable, allowing us to employ Bash integer expressions such as the condition in

Learn More

Project 87 gives tips on declaring variables and Bash integer arithmetic.


while ((len!=0));


which loops for as long as the value of the variable len is not equal to 0; and the arithmetic expression

len=len-1


which subtracts 1 from the value of len.

Learn More

Project 81 covers Bash conditions.


We'd call Underline from the main body of the script in the following manner.

Underline "The Title"


yielding

The Title ---------


Tip

To find out more about the local commandwhich, when used within a function, is equivalent to the declare commandtype

$ help local $ help declare






Mac OS X UNIX 101 Byte-Sized Projects
Mac OS X Unix 101 Byte-Sized Projects
ISBN: 0321374118
EAN: 2147483647
Year: 2003
Pages: 153
Authors: Adrian Mayo

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