Unix command line 101: How much do you know?

Unix Insider –

A Unix command line is a sequence of characters in the syntax of the target shell language. Of the characters found there, some are known as metacharacters, which have a special meaning to the shell. The metacharacters in the Korn shell are:

  • <font face="Courier">;</font>
    Separates multiple commands on a command line
  • <font face="Courier">&</font>
    Causes the preceding command to execute synchronously (i.e., at the same time as the next command on the command line)
  • <font face="Courier">()</font>
    Launches commands enclosed in parentheses in a separate shell
  • <font face="Courier">|</font>
    Pipes the output of the command to the left of the pipe to the input of the command on the right of the pipe
  • <font face="Courier">></font>
    Redirects output to a file or device
  • <font face="Courier"><</font>
    Redirects input from a file or device
  • Newline Ends a command or set of commands
  • Space Separator between command words
  • Tab Separator between command words

(Note: Some of these metacharacters can be used in combinations, such as

<font face="Courier">||</font>
and
<font face="Courier">&&</font>
. Consult your manual for a complete description.)

With these metacharacters in mind, you can define a command line word -- a sequence of characters separated by one or more nonquoted metacharacters. In the following example, the

<font face="Courier">passwd</font>
file is piped through the
<font face="Courier">cut</font>
program, and fields 1 and 3 are output based on a colon delimiter.

In the following command line,

<font face="Courier">cat /etc/passwd|cut -d ":" -f 1,3 >usruid.txt
</font>

the words are:

<font face="Courier">cat
/etc/passwd
cut
-d
":"
-f
1,3
usruid.txt
</font>

Note that the metacharacters

<font face="Courier">|</font>
,
<font face="Courier">></font>
, and the space have been removed, and that the metacharacters
<font face="Courier">&</font>
,
<font face="Courier">|</font>
,
<font face="Courier">()</font>
,
<font face="Courier">;</font>
, and the newline are used to separate or terminate multiple commands within a command line.

In our example command line, there are two commands separated by the pipe (

<font face="Courier">|</font>
) symbol:

<font face="Courier">cat /etc/passwd
</font>

and

<font face="Courier">cut -d ":" -f 1,3
</font>

The final portion of the command line --

<font face="Courier">>usruid.txt</font>
-- could be thought of as the command "and output the result to
<font face="Courier">usruid.txt</font>
," although redirection is not usually considered part of a command.

When a command executes a Unix program, utility, or shell script, it's usual for the command to include arguments. In the example above, the argument to

<font face="Courier">cat</font>
is
<font face="Courier">/etc/passwd</font>
. The arguments to
<font face="Courier">cut</font>
are
<font face="Courier">-d</font>
,
<font face="Courier">":"</font>
,
<font face="Courier">-f</font>
, and
<font face="Courier">(1,3)</font>
.

In general, arguments are all the words (note the definition of word above) that follow an executable program name in a command. Arguments within a command are separated from one another by spaces or tabs (metacharacters). Most Unix programs were written with standards for the arrangement of arguments and options.

Options are the letters or numbers that follow a minus sign. A simple example of arguments and options would be the use of the

<font face="Courier">cat</font>
command:

<font face="Courier">cat -v -e -t doodah.txt
</font>

In the above example, the arguments are

<font face="Courier">-v</font>
,
<font face="Courier">-e</font>
,
<font face="Courier">-t</font>
, and
<font face="Courier">doodah.txt</font>
, while the options are the entries for
<font face="Courier">-v</font>
,
<font face="Courier">-e</font>
, and
<font face="Courier">-t</font>
. The
<font face="Courier">-v</font>
option asks
<font face="Courier">cat</font>
to display all characters, even nonprintable ones; the
<font face="Courier">-e</font>
option specifies that the end of a line will be displayed as
<font face="Courier">$</font>
; and the
<font face="Courier">-t</font>
option specifies that a tab should be displayed as
<font face="Courier">^I</font>
instead of expanding the tab into spaces on the screen.

Unfortunately, no standard terminology has been developed to differentiate an option from a nonoption argument, which is all the more confusing when one considers that an option can itself have an argument. In the first example using

<font face="Courier">cut</font>
, the
<font face="Courier">-d</font>
option has an option argument of
<font face="Courier">":"</font>
, and the
<font face="Courier">-f</font>
option has an option argument of
<font face="Courier">(1,3)</font>
. In order to clarify these, various manuals have adopted standards for naming conventions for the parts of a Unix command. The following examples illustrate the parts:

<font face="Courier">cat -v -e -t doodah.txt
</font>
<font face="Courier">cat /etc/passwd|cut -d ":" -f 1,3 >usruid.txt
</font>

The program name itself,

<font face="Courier">cat</font>
in the first example and
<font face="Courier">cat</font>
and
<font face="Courier">cut</font>
in the second, is variously called the name, progname, executable, or program-name. The nonoption arguments to a command,
<font face="Courier">doodah.txt</font>
in the first example and
<font face="Courier">/etc/passwd</font>
in the second, is called an operand or cmdarg.

The options

<font face="Courier">-v</font>
,
<font face="Courier">-e</font>
, and
<font face="Courier">-t</font>
in the first example, and
<font face="Courier">-d</font>
and
<font face="Courier">-f</font>
in the second, are called options, opts, or switches. The arguments to options,
<font face="Courier">":"</font>
and
<font face="Courier">(1,3)</font>
in the second example are called option-arguments, or optargs.

The standards used in creating Unix executables are:

  1. Command names must be between two and nine characters long

  2. Command names must include only lowercase letters and digits

  3. Option names (options above) must be only one character long

  4. All options must be preceded by

    <font face="Courier">-</font>

  5. Options with no arguments may be grouped after a single

    <font face="Courier">-</font>
    (e.g.,
    <font face="Courier">-v -e -t</font>
    could also be written as
    <font face="Courier">-vet</font>
    )

  6. The first option-argument following an option must be preceded by white space

  7. Option-arguments cannot be optional

  8. Groups of option-arguments following an option must either be separated by commas or by white space, and quoted (e.g.,

    <font face="Courier">-f 1,3</font>
    or
    <font face="Courier">-o "xxx z yy"</font>
    )

  9. All options must precede operands on the command line

  10. <font face="Courier">--</font>
    may be used to indicate the end of the options

  11. The order of the options relative to one another should not matter

  12. The relative order of the operands (cmdargs) may affect their significance in ways determined by the command with which they appear

  13. <font face="Courier">-</font>
    preceded and followed by white space should only be used to mean standard input

Not all Unix commands follow these rules, although all the newer ones do. Older executables were written before the standard was established, but executables dating from these times are in such regular use that it was decided not to change them. For example,

<font face="Courier">cut</font>
will function with or without rule number six, which requires a space before the option-argument. Both of the following commands will work on most systems.

<font face="Courier">cat /etc/passwd|cut -d ":" -f 1,3 >usruid.txt
cat /etc/passwd|cut -d: -f1,3 >usruid.txt
</font>

The

<font face="Courier">find</font>
command is another example of an antiquated program still in use today. It uses options longer than a single character, which violates rule number three, and allows options to appear after the operand, thus violating rule number nine. In the following example, dot (
<font face="Courier">.</font>
) is the operand,
<font face="Courier">-name</font>
and
<font face="Courier">-print</font>
are options, and
<font face="Courier">data.txt</font>
is the option-argument for
<font face="Courier">-name</font>
.

<font face="Courier">find . -name data.txt -print.
</font>

The getopts function

You're probably wondering what all this blather is leading up to. Well, Unix provides a handy tool for separating option arguments and operands, and it's known as the

<font face="Courier">getopts</font>
function. This function is called by following
<font face="Courier">getopts</font>
with a string (which contains the list of valid option characters) and a shell variable (which receives the result of searching the arguments). The function can be called several times, and each time it steps forward through the list of arguments and picks up the next option. It can also pick up an option-argument, and the index of the argument that it has processed.

To illustrate this, imagine a shell script that will archive a file by copying it to an archive directory. The default directory is

<font face="Courier">/u/arch</font>
, but the path of the archive directory can be changed on the command line. The archive program will also stop and ask you if it is about to overwrite an earlier archive, but an option can be set to overwrite without warning. A sample command line for this archive program would be:

<font face="Courier">arch [-r] [-a /new/archive/path] filename
</font>

In this example, the

<font face="Courier">-r</font>
option will automatically replace an existing archive file without warning, though the default is to warn. The
<font face="Courier">-a</font>
option is followed by an alternative archive directory to use instead of
<font face="Courier">/u/archive</font>
. Finally,
<font face="Courier">filename</font>
is the name of the file to archive.

The following is a listing for

<font face="Courier">arch</font>
that covers the processing of the option arguments. It does not include the logic for doing the actual archive operation. Below the complete listing is a step-by-step analysis of how the program works.

<font face="Courier">#! /bin/sh
#:------------------------------------------------------------
--
usage () {
 echo "Usage:"
 echo "arch - archives a file to /u/arch directory"
 echo "syntax:"
 echo "    arch [-r] [-a /new/archive/path] filename"
 echo "where"
 echo "    -r will automatically replace an existing archive
file"
 echo "       (default is to warn)"
 echo "    -a specifies an alternative archive directory"
 echo "    filename is the name of the file to archive"
 exit
}
#:------------------------------------------------------------
--

replace="w"
arch="/u/arch"
filename=""

optstr=":ra:"

while getopts $optstr opt
do

    case $opt in
        r) replace="r";;
        a) arch=$OPTARG;;
        *) usage;;
    esac
done

shift `expr $OPTIND - 1`

filename=$1

echo "Archiving" $filename " to " $arch "with" $replace
"replace option"

# rest of the code goes here

</font>

The

<font face="Courier">getopts</font>
function does not always work correctly with the Korn shell, so line 1 forces the script to run in the Bourne shell. The program begins lines 2 through 15 with a comment describing its actions that also doubles as a usage function, which is called when the user makes a mistake.

<font face="Courier"> 1   #! /bin/sh
 2  
#:------------------------------------------------------------
--
 3   usage () {
 4    echo "Usage:"
 5    echo "arch - archives a file to /u/arch directory"
 6    echo "syntax:"
 7    echo "    arch [-r] [-a /new/archive/path] filename"
 8    echo "where"
 9    echo "    -r will automatically replace an existing
archive file"
10    echo "       (default is to warn)"
11    echo "    -a specifies an alternative archive
directory"
12    echo "    filename is the name of the file to archive"
13    exit
14   }
15  
#:------------------------------------------------------------
--
</font>

Shell variables are set up at lines 17 and 18 and contain the default values used for archiving and the archive directory, and makes a replacement warning default behavior. Line 19 sets up a variable for the file to be archived:

<font face="Courier">17   replace="w"
18   arch="/u/arch"
19   filename=""
</font>
1 2 Page
Insider: How the basic tech behind the Internet works
Join the discussion
Be the first to comment on this article. Our Commenting Policies