Teach Yourself UNIX Shell Programming in 14 Days

Chapter 8: Introduction to Shell Scripts


This chapter (finally) discusses creating shell scripts and offers suggestions about handling input to them. Objectives important to this chapter are:

  • creating a shell script
  • methods of executing a script
  • passing arguments to a script
  • integer math
  • debugging

A shell script is compared to DOS batch file by our author. He states that both are useful for executing a series of operating system commands in an automated way instead of doing so from the command line.

Any text editor available to a user in the UNIX environment can be used to create a script. If you don't have access to one (like vi or pico) you can always write short files with the command

	cat > script_name

Like any program, a script should be properly documented for those who have to follow the creator and add to it (or fix it.) Use the pound sign to mark comments in your scripts.

Once you have written a script and saved it as a file, you should set proper execute permissions for it. This can be done a number of ways. This command

	chmod +x script1

would add execute permissions to the file called script1 for all system users. Using a minus sign instead of a plus sign would remove execute permissions for all users. (Again, an unusual use of the hyphen character. It generally just means "here comes a modifier".)

This command is more precise:

	chmod u+x script2

It is precise in that it turns on the execute permissions only for the user who owns the file (as opposed to a g for group, or o for others.) However, it does not tell us what permissions anyone else already has.

I prefer to use the variation

	chmod 755 script

because it sets each permission for each level of user at once, and I am not left in doubt about what any user can do.

However, there are always exceptions to UNIX rules. Even without execute permissions, we can execute a file by preceding its name on a command line with a period and a space, or by preceding it with a call to a shell program and a space:

	. script
	sh script

Scripts may accept arguments on the command lines that call them. Multiple word phrases that are meant to be single arguments should be enclosed in quotation marks. For instance,

	script1 red white blue

illustrates calling the script named script1, and passing it 3 arguments (red, white and blue.) This example,

	script2 "red white blue"

calls script2 and passes it one argument that consists of a three word phrase.

Up to nine arguments passed to a script will be saved in numbered variables, 1 through however many arguments. In the 3 argument example above,

	script1 red white blue

$1 would equal "red", $2 would equal "white" and $3 would equal "blue". The $0 is a special value that holds the path to the script itself. $# holds the number of arguments passed to the script, and $* holds the entire list of arguments.

If more than nine arguments are passed to a script, you have to get at the tenth (and later ones) with the shift command. This command takes the queue of arguments (they are held, just not numbered after 9) and throws out the first one, reassigning the remaining arguments to 1 through 9, and holding any extra. The shift command can be given a numeric argument, such as 6, which would discard the first six, and then reassign 1 through 9 from the remaining members of the argument queue.

Integer math can be done as discussed in earlier chapters, using the expr command and accents grave. The new idea here is that it can be done in a script using the arguments passed to the script and numbered variables holding those arguments.

When calling a shell to run a script, such as

	sh script argument1 argument2

you can pass a parameter to the shell that engages a rudimentary debugger. The -v switch is used thus:

	sh -v script argument1 argument2

This causes the line being executed to be echoed to the screen before its output, allowing the programmer to see what the result of each line is, and to decide if it is the desired result. Another switch, -x prints out each script line, not as it was written, but as it is executed, that is, as the processor sees it, including the current value of each variable. The two switches can be combined as one, either -vx or -xv, and you get both forms of output to the screen.