Shell scripts are text files, so you create them the same way as any other text file. At the command line, that typically means using an editor like vi , nano , or emacs , but you can also use a GUI text editor or even a word processor. Just be sure to save the files as plain-text files (often called "Text Only" in save-file dialogs), which means no font information, no boldface or underlining, just plain text. (Review Chapter 5, "Using Files and Directories," for details on editing files from the command line.)
The first task simply takes you through the steps of creating an extremely minimal script. Subsequent tasks add features to the script covering the basic elements of scripting:
Using control structures
Getting user input
Creating and using functions
To create a simple shell script:
Create a new file called myscript.sh in your text editor.
The filename can actually be anything you like. The .sh extension indicates that the file is a Bourne shell script; however, this is simply a file-naming convention and is not required. It is the first line of the file itself that determines the kind of script.
Enter the first line of the script:
Make sure there are no spaces before the # . This first line is very special. See the sidebar "The All-Important Shebang Line of a Script."
This script is a Bourne shell script. The commands in it are read and executed by the program /bin/sh .
Enter a comment to describe what the script does.
Lines that begin with just a # are comments and are ignored when the script is executed, as are blank lines. (Exception: the very first line, as described in the sidebar "The All-Important Shebang Line of a Script.")
# This script just says hello.
Enter the first actual command line in the script:
echo "Hello, I am a script."
Notice that this line would work perfectly well if you entered it at the command line, even if you are using a shell other than the Bourne shell, such as the tcsh shell. That's because the lines in shell scripts are simply Unix command lines. Even though this script uses the Bourne shell, many command lines are identical in both the Bourne and tcsh shells . The echo command in this example is a separate program ( /bin/echo ), executed by the Bourne shell when it gets to this line in the script.
Save the file.
Use the appropriate command for your editor to save the file.
Quit the editor.
You should be back at a shell prompt.
Now you must make the script executable.
chmod 755 myscript.sh
Changing the mode to 755 (review modes in Chapter 8, "Working with Permissions and Ownership") gives anyone the ability to read and execute the script file, while giving you (the owner) the additional permission to edit it.
You can now execute the script with the command line
Figure 9.1 shows a code listing of the script, and Figure 9.2 shows the result of running it from the command line.
Figure 9.1. Code listing of a simple script. It has only one line of executable code.
#!/bin/sh # This script just says hello. echo "Hello, I am a script."
Figure 9.2. Running the new script from the command line.
localhost:~ vanilla$ ./myscript.sh Hello, I am a script. localhost:~ vanilla
You need to use the ./ to specify a path to the script because the script is not in your PATH (which is the list of places where your shell looks for commands; see "Environment Variables" in Chapter 7, "Configuring Your Environment with Unix"). But see the next task to learn how to have the script be available just like any other commandthat is, without having to type the path to it but simply by typing the script name .
You can run a shell script by typing its name on the command line, just as if it were any other Unix command. In order for this to work, you must do a few things with the script, described in the following task.
To create a shell script that can be used like a command:
Make sure the script is executable.
Make sure the script is in a directory listed in your PATH environment variable.
For most scripts you create for your own personal use, the best place to put them is in your ~/bin directorythat is, the bin directory inside your home directory. This directory is not installed with Mac OS Xyou need to create it. (Remember: The ~ character is a shortcut for specifying your home directory.)
If you have not already done so, you should add your ~/bin directory to your PATH environment variable (instructions for doing this are in the "Changing your PATH " section of Chapter 7). Scripts intended for systemwide use should go in /usr/local/bin . ( /usr/local should already exist on your system, but you may need to create /usr/local/bin ).
You can either create the script in the appropriate place to begin with, or use the cp or mv command to copy or move the script into placefor example,
If ~/bin does not exist, then create it with
Move the script into ~/bin :
mv myscript.sh ~/bin/
You can now run the script by simply typing its name.
If you are using the tcsh shell, you'll need to run the rehash command for any shell that is already running. When it starts up, the tcsh shell scans the directories listed in your PATH .
Be careful about creating scripts that have the same names as existing commands.
The standard date command is /bin/date . If you use date on a command line without specifying a path, then a date script in either ~/bin or /usr/local/bin is executed instead of the standard /bin/date command. This is because the shell looks in the directories in your PATH in order, and your ~/bin directory and /usr/local/bin are listed earlier than /bin in your PATH .
The All-Important Shebang Line of a Script
In a shell script, the # character at the start of a line marks that line as a commentto be ignored when the script is executed. But when the first two characters in a file are #! , then the rest of the first line is assumed to be a path to a program that knows how to execute the rest of the file (an interpreter ). The operating system executes the interpreter and hands it the script file as input. If the first two characters are not #! , then the operating system assumes that the file consists of compiled machine-readable binary code and will try to execute it directly.
The # character is often called a sharp (as it is in musical notation), and the ! character in Unix is pronounced "bang" (the literal sense of an exclamation point), hence shebang .
This trick of looking at the first two bytes of a file has been part of Unix for more than 20 years , starting in an early version of BSD Unix version 4, around early 1980. The shebang line is one of the mechanisms that make shell scripts so common in Unix.
You can still run a shell script without the shebang line by supplying the script filename as an argument to the shell program itselffor example,
passes myscript as an argument to the sh command, which will then read the file as series of commands, ignoring any shebang line (because the shebang line looks like a comment).
So if the first line of the file contains
the operating system will execute the program located at /bin/sh and feed it the whole file as input.
If the first line of a script is
when you run it, you will probably get the error message "Command not found." Why? Because when you run the script, the operating system looks for bin/sh and doesn't find it. The line is missing the / before bin . A simple typographical error like that can lead to a lot of frustration. (Extra credit: Can you think of a situation in which that typo would not cause an error message? Hint: What if your working directory is / ?)