The shell executes a program when you give it a command in response to its prompt. For example, when you give the ls command, the shell executes the utility program named ls. You can cause the shell to execute other types of programssuch as shell scripts, application programs, and programs you have writtenin the same way. The line that contains the command, including any arguments, is called the command line. In this book the term command refers to the characters you type on the command line as well as to the program that action invokes.
Command line syntax dictates the ordering and separation of the elements on a command line. When you press the RETURN key after entering a command, the shell scans the command line for proper syntax. The syntax for a basic command line is
command [arg1] [arg2] ... [argn] RETURN
One or more SPACEs must separate elements on the command line. The command is the name of the command, arg1 through argn are arguments, and RETURN is the keystroke that terminates all command lines. The brackets in the command line syntax indicate that the arguments they enclose are optional. Not all commands require arguments: Some commands do not allow arguments; other commands allow a variable number of arguments; and others require a specific number of arguments. Options, a special kind of argument, are usually preceded by one or two hyphens (also called a dash or minus sign: -).
Some useful Mac OS X command lines consist of only the name of the command without any arguments. For example, ls by itself lists the contents of the working directory. Most commands accept one or more arguments. Commands that require arguments typically give a short error message, called a usage message, when you use them without arguments, with incorrect arguments, or with the wrong number of arguments.
On the command line each sequence of nonblank characters is called a token or word. An argument is a token, such as a filename, string of text, number, or other object that a command acts on. For example, the argument to a vim or emacs command is the name of the file you want to edit.
The following command line shows cp copying the file named temp to tempcopy:
$ cp temp tempcopy
Arguments are numbered starting with the command itself as argument zero. In this example cp is argument zero, temp is argument one, and tempcopy is argument two. The cp utility requires two arguments on the command line. (The utility can take more arguments but not fewer; see page 690.) Argument one is the name of an existing file. Argument two is the name of the file that cp is creating or overwriting. Here the arguments are not optional; both arguments must be present for the command to work. When you do not supply the right number or kind of arguments, cp displays a usage message. Try typing cp and then pressing RETURN.
An option is an argument that modifies the effects of a command. You can frequently specify more than one option, modifying the command in several different ways. Options are specific to and interpreted by the program that the command line calls, not the shell.
By convention options are separate arguments that follow the name of the command and usually precede other arguments, such as filenames. Most utilities require you to prefix options with a single hyphen. However, this requirement is specific to the utility and not the shell. GNU program options are frequently preceded by two hyphens in a row. For example, --help generates a (sometimes extensive) usage message.
Figure 5-1 first shows what happens when you give an ls command without any options. By default ls lists the contents of the working directory in alphabetical order, vertically sorted in columns. Next the -r (reverse order) option causes the ls utility to display the list of files in reverse alphabetical order, still sorted in columns. The -x option causes ls to display the list of files in horizontally sorted rows.
Figure 5-1. Using options
$ ls alex jenny office temp hold mark oldstuff test house names personal $ ls -r test oldstuff mark hold temp office jenny alex personal names house $ ls -x alex hold house jenny mark names office oldstuff personal temp test $ ls -rx test temp personal oldstuff office names mark jenny house hold alex
When you need to use several options, you can usually group multiple single-letter options into one argument that starts with a single hyphen; do not put SPACEs between the options. You cannot combine options that are preceded by two hyphens in this way, however. Specific rules for combining options depend on the program you are running. Figure 5-1 shows both the -r and -x options with the ls utility. Together these options generate a list of filenames in horizontally sorted columns, in reverse alphabetical order. Most utilities allow you to list options in any order; thus ls -xr produces the same results as ls -rx. The command ls -x -r also generates the same list.
Tip: Displaying readable file sizes: the -h option
Most utilities that report on file sizes specify the size of a file in bytes. Bytes work well when you are dealing with smaller files, but the numbers can be difficult to read when you are working with file sizes that are measured in megabytes or gigabytes. Use the -h (human readable) option to display file sizes in kilo-, mega-, and gigabytes. Experiment with df -h (disk free) and ls -lh commands.
Some utilities have options that themselves require arguments. For example, the gcc utility has a -o option that must be followed by the name you want to give the executable file that gcc generates. Typically an argument to an option is separated from its option letter by a SPACE:
$ gcc -o prog prog.c
Arguments that start with a hyphen
Another convention allows utilities to work with arguments, such as filenames, that start with a hyphen. If a file's name is -l, the following command is ambiguous:
$ ls -l
This command could mean a long listing of all files in the working directory or a listing of the file named -l. It is interpreted as the former. You should avoid creating files whose names begin with hyphens. If you do create them, many utilities follow the convention that a -- argument (two consecutive hyphens) indicates the end of the options (and the beginning of the arguments). To disambiguate the command, you can type
$ ls -- -l
You can use an alternative format in which the period refers to the working directory and the slash indicates that the name refers to a file in the working directory:
$ ls ./-l
Assuming that you are working in the /Users/zach directory, the preceding command is functionally equivalent to
$ ls /Users/zach/-l
You can give the following command to get a long listing of this file:
$ ls -l -- -l
These are conventions, not hard-and-fast rules, and a number of utilities do not follow them (e.g., find). Following such conventions is a good idea; it makes it much easier for users to work with your program. When you write shell programs that require options, follow the standard option conventions.
Tip: The GNU --help option
Many utilities display a (sometimes extensive) help message when you call them with an argument of --help. All utilities developed by the GNU project (page 4) accept this option. An example follows.
$ bzip2 --help bzip2, a block-sorting file compressor. Version 1.0.2, 30-Dec-2001. usage: bzip2 [flags and input files in any order] -h --help print this message -d --decompress force decompression -z --compress force compression -k --keep keep (don't delete) input files -f --force overwrite existing output files -t --test test compressed file integrity -c --stdout output to standard out -q --quiet suppress noncritical error messages -v --verbose be verbose (a 2nd -v gives more) ...
Processing the Command Line
As you enter a command line, the Mac OS X tty device driver (part of the Mac OS X operating system kernel) examines each character to see whether it must take immediate action. When you press DELETE (to erase a character) or CONTROL-U (to kill a line), the device driver immediately adjusts the command line as required; the shell never sees the character(s) you erased or the line you killed. Often a similar adjustment occurs when you press CONTROL-W (to erase a word). When the character you entered does not require immediate action, the device driver stores the character in a buffer and waits for additional characters. When you press RETURN, the device driver passes the command line to the shell for processing.
Parsing the command line
When the shell processes a command line, it looks at the line as a whole and parses (breaks) it into its component parts (Figure 5-2). Next the shell looks for the name of the command. Usually the name of the command is the first item on the command line after the prompt (argument zero). The shell takes the first characters on the command line up to the first blank (TAB or SPACE) and then looks for a command with that name. The command name (the first token) can be specified on the command line either as a simple filename or as a pathname. For example, you can call the ls command in either of the following ways:
$ ls $ /bin/ls
Figure 5-2. Processing the command line
Absolute versus relative pathnames
When you give an absolute pathname on the command line or a relative pathname that is not a simple filename (i.e., any pathname that includes at least one slash), the shell looks in the specified directory (/bin in the case of the /bin/ls command) for a file that has the name ls and that you have permission to execute. When you give a simple filename, the shell searches through a list of directories for a filename that matches the specified name and that you have execute permission for. The shell does not look through all directories but only the ones specified by the variable named PATH. Refer to page 285 (bash) or page 359 (tcsh) for more information on PATH. Also refer to the discussion of the which and type utilities on page 58.
When it cannot find the executable file, the Bourne Again Shell (bash) displays a message such as the following:
$ abc bash: abc: command not found
One reason the shell may not be able to find the executable file is that it is not in a directory in your PATH. Under bash the following command temporarily adds the working directory (.) to your PATH:
For security reasons, you may not want to add the working directory to PATH permanently; see the adjacent tip and the one on page 286.
Tip: Try giving a command as ./command
You can always execute an executable file in the working directory by prepending ./ to the name of the file. For example, if toad is an executable file in the working directory, you can execute it with the following command:
When the shell finds the program but cannot execute it (you do not have execute permission for the file that contains the program), it displays a message similar to
$ def bash: ./def: Permission denied
See "ls -l: Displays Permissions" on page 87 for information on displaying access permissions for a file and "chmod: Changes Access Permissions" on page 88 for instructions on how to change file access permissions.
Executing the Command Line
If it finds an executable file with the same name as the command, the shell starts a new process. A process is the execution of a command by Mac OS X (page 293). The shell makes each command line argument, including options and the name of the command, available to the called program. While the command is executing, the shell waits for the process to finish. At this point the shell is in an inactive state called sleep. When the program finishes execution, it passes its exit status (page 564) to the shell. The shell then returns to an active state (wakes up), issues a prompt, and waits for another command.
The shell does not process arguments
Because the shell does not process command line arguments but only hands them to the called program, the shell has no way of knowing whether a particular option or other argument is valid for a given program. Any error or usage messages about options or arguments come from the program itself. Some utilities ignore bad options.