[Next] [Previous] [Up] [Top] [Contents] [Index]

Chapter 4: Shells

4.4 Shell Scripts

As mentioned above, a UNIX shell can be used as an interpretive programming language. Besides executing shell commands within the script, you can:

A shell script is a file containing a sequence of commands which can be executed by the shell, and flow control commands. The same syntax is used for commands within scripts as for interactive command entry. Section 5.1 explains briefly how the system runs and interprets shell scripts.

Although you can write complex programs using the shell language, you can also create simple shell scripts for running long commands or a series of commands that you use frequently.

In every shell script you write, include the special characters #! followed by the pathname of the shell as the first characters in the file. This indicates (a) that this is a script rather than a compiled executable, and (b) which shell to invoke to run the script.[13]

For example:

#!/usr/local/bin/bash

at the start of the script invokes bash to run it. A # found anywhere else in the script is interpreted as the beginning of a comment, and the shell ignores all characters between the # symbol and the next newline character.

An introductory reference for script-writing with examples can be found in UNIXHelp on the Web. You can get to it via the UNIX Resources page under The UNIX Operating System.

Note that in order to execute the script, regardless of shell, the script file must have execute permission for the appropriate users (see section 6.6.1 for a discussion of permissions). After you set this permission, the shell will need to rebuild its "hash table" to include the new script. The hash table is a table of executables that the shell recognizes.

To complete these two operations, enter:

% chmod a+x filename
% rehash[14] 

To run a script, the shell must be able to locate it. If its directory is in your path (see section 9.2), you only need to type the script's filename to run it. If not, you can type the the filename preceded by ./ on the command line (the ./ explicitly tells the shell to look for the executable file in the current working directory). Typing the full path of the filename will work too, although it is perhaps the most cumbersome way of telling the shell where the script is. Here we illustrate the three ways to invoke a script:

% filename
% ./filename
% /full_path/.../filename

Once the shell locates the script, it interprets and executes the commands in the file one by one.

You may want to maintain a $HOME/bin directory for all your programs and shell scripts, and include this directory in your path[15]. The shell uses this variable to locate commands and other executables.

It is important to remember that, like all UNIX commands that are not part of the shell (see section 5.1.1 for an explanation of shell commands), the script file executes in a subshell forked[16] by the parent shell. This subshell retains any environment variables defined in the script as well as any shell variables defined in the file .cshrc or .shrc (one of these two files may be executed automatically prior to the script, depending on your shell; see section 9.4). At the end of the script, control returns to the parent shell, and any definitions made by the subprocess are not passed back to the parent process.

To execute a script for which you do want to pass back changes to the parent shell (for example, setting new shell variables), the syntax for execution differs. For the C shell family, execute the script by typing:

% source filename

For the Bourne shell family, type:

$ . filename

The source or . command executes the script in the context of your current process, so that you can affect this current process, in contrast to normal command execution.

For instance, after you make changes to your .cshrc or .login file, you can use source or . to execute it from within the login shell in order to put the changes into effect.


[13] On some of the more recent OS releases (e.g., AIX+4 and IRIX+6.4, and likely others in the near future) /bin/sh is a link to the korn shell (ksh). Therefore on these platforms, the .shrc file (see section 9.4.2) gets sourced for any script starting with #!/bin/sh.
[14] The command in sh is hash; not necessary in other shells.
[15] Under FUE, the Fermi files add your /bin directory to your PATH.
[16] Under UNIX, the term fork means create a new process.

UNIX at Fermilab - 10 Apr 1998

[Next] [Previous] [Up] [Top] [Contents] [Index]