Shell command execution
The best way to learn shell scripting is by example. Any command that you would execute in a script you can try right at the command line, and that's how many of the hands-on examples are given throughout this tutorial. For example, the
echo command writes a line of text to the standard output. (Many shells offer their own version of
echo as a built-in command, including the IBM AIX® implementation of the Bourne shell. If that's your case, then when you run
echo, it's actually your shell's version of the command that's being run.)
Try outputting a short message with
echo by enclosing it in quotes:
$ echo "Hello, world" Hello, world
Shell quotation, either right at the command line or in scripts, is a means of passing a string to the shell so that there is no ambiguity about any of the special metacharacters that the string might contain. You use quotation when strings contain more than a single word and to enclose a phrase containing space characters. You also quote an individual character when it happens to be a shell metacharacter and you want to take away its special meaning, such as when you want to pass a dollar sign (
$) as a literal dollar sign character and not the special metacharacter that precedes a variable name.
Various expansion occurs inside quoted text. Inside of double-quoted text, for instance, variables are expanded to their values, while literal variable names are not expanded when referenced inside of single-quoted text.
There are three important types of quotation to know:
Quote a single character by preceding it with a backslash (\). This passes the literal character and not any special meaning it might have, such as a space character or shell metacharacter. For instance, to quote an asterisk (*), which is a shell metacharacter, use
\*. To quote an actual backslash character, use
Pass an expanded quotation by enclosing a text string in double quotation marks (
"). The dollar sign (
$) and single quotation mark (
') characters keep their meanings. So, among other things, any variable names referenced in the quotation are replaced by their values. Backslashes that precede a new line or certain characters (
$`"\) are removed, but the characters they quote are passed.
Pass a literal quotation of a text string -- passing all variable names, metacharacters, and so on as the characters themselves and not their meanings or values -- by enclosing the text in single quotation marks (
Note that the exact rules of quotation differ across shells. Consult the
man pages of your particular
shell to see its precise rules.
Try assigning a variable and then outputting it with various quotation styles, as shown in Listing 1.
Listing 1. Demonstrating shell variable quotation styles with echo
$ myvar = "Hello, world" $ echo $myvar Hello, world $ echo "$myvar" Hello, world $ echo '$myvar' $myvar $ echo \$myvar $myvar $ echo \'$myvar\' 'Hello, world' $ echo "'$myvar'" 'Hello, world' $ echo '"$myvar"' "$myvar" $ echo \"$myvar\" "Hello, world"
Notice how the variable is interpreted in different ways depending on the quoting style used.
In the shell, the hash mark (
#) begins a comment line. The hash and everything that follows it on the line is ignored. Try typing lines interspersed with comments, as shown in Listing 2:
Listing 2. Using comments in the shell
$ # a comment does nothing $ echo "Hello, world" # This text is ignored Hello, world $ echo # This will not output $ echo 'But a hash (#) can be quoted' But a hash (#) can be quoted $ echo "# Even in double quotes" # Even in double quotes $
As you can see, you can work right at the command line to test these shell programming constructs. But, when you graduate beyond one-line commands and actually start composing longer programs, you need to write them to files called scripts. A script is a text file that has its executable bit set and contains a program consisting of commands in the shell language. The UNIX shell is an interpreted language, meaning that its programs are not compiled but are read by an interpreter, which is the shell executable itself, such as
The first line of a shell script is always the same:
This is a special comment line used by the shell itself to determine the language or contents of the file. The exclamation point, often called bang in the UNIX and typesetting idioms, followed by the path name indicates the interpreter the shell should use to execute the file. In this case, it's
/bin/sh, which on many systems is the Bourne shell executable itself. A script written specifically
for the Korn shell, for example, might begin with the line
#!/usr/bin/ksh instead, just as a Ruby script would begin with
bash is installed,
/bin/sh is usually a symbolic link to the
bash binary. And, for compatibility, using
/bin/sh is preferable to using
/bin/bash. On some systems, such as IBM AIX 5L™, the name for the Bourne shell executable is
bsh, and it's located at /usr/bin/bsh.
Listing 3 gives a short example shell script.
Listing 3. Sample shell script
#!/bin/sh # This is a shell script message = "Hello, world!" echo "The message is '"$message"'"
vi to type it in and save it to a file named myscript, as described in a previous tutorial in this series (see Resources). Then, use
chmod to make it executable by setting execute permission on the file:
$ chmod u+x myscript
This command makes it executable only by you. If you want to let all users on the system run it, you can always set the execute permission for all:
$ chmod a+x myscript
Now you can run it. Give the file name as it exists in relation to the current working directory, which is specified in the path as a dot character (
$ ./myscript The message is 'Hello, world!' $
The shell variable
PATH contains a list of directories delimited by colons. This is said to be your path, and the shell always "sees" any files in those directories. The purpose of the UNIX path is to make it convenient to run binary files. That's why you just type the base file names of commands, such as
echo, instead of giving their full or relative path names. If you move the script to a directory on your path, you can just type its name to run it. The exact path depends on your UNIX implementation and local setup, but normally the directories on the path include /bin, /usr/bin, and /usr/local/bin.
Some users configure their shell so that the
PATH variable includes the current working directory, which is specified in the path as a dot character, ("
."). That way, to run a script in the current directory, you can just type its name without specifying the relative directory. The shell searches along the path in the order given; so to protect against trojans or accidental mishaps, it's never wise to put the current working directory anywhere but at the end of the path.
To see your path, use
echo to show the contents of the
PATH variable, as shown in Listing 4.
Listing 4. Changing the PATH
$ echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/bin/X11 $ myscript myscript: command not found $ PATH = $PATH":." $ echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/bin/X11:. $ myscript The message is 'Hello, world!' $
Special options or flags can follow the name of the interpreter, such as
/usr/bin/bsh -n, which is used for debugging purposes. A hyphen turns the option off, while a plus turns the option on. The special built-in environment variable,
- (a hyphen), contains the full list of options for the current shell.
Try showing which options are set in your current interactive shell. Do this by using
echo to display the contents of the
$ echo $- himBH $
man page of your shell to get a current list of flags and options. Table 1 provides a list of common flags for the Bourne shell on AIX®, along with a short description of what each one does.
Table 1. Common options for the AIX Bourne shell
||Export all variables that are assigned values.|
||Execute the commands read from Variable.|
||Exit immediately if a command meets one of the following criteria: the command exits with a return value greater than 0; the command
isn't part of a |
||Disable all filename substitution.|
||Locate and remember all commands called within the functions as the functions are defined.|
||Specify an interactive shell.|
||Place all keywords in the environment for the command.|
||Read commands, but don't execute them.|
||Call a restricted shell.|
||Read commands from standard input, and write output to standard error (excluding the output of shell built-ins).|
||Read and execute one single command, and then exit.|
||In scripts, treat all unset variables as errors. Exit upon attempting variable substitution.|
||Show the input line as it's being read.|
||Show the full commands (all arguments and options) before executing them.|