Sams Teach Yourself Shell Programming in 24 Hours
(Publisher: Macmillan Computer Publishing)
Author(s): Sriranga Veeraraghavan
ISBN: 0672314819
Publication Date: 01/01/99

Previous Table of Contents Next


Hour 18
Miscellaneous Tools

by Frank Watson


In this chapter, you will look at several miscellaneous UNIX commands that you often encounter in shell scripts and can use in your own programs. The first of these tools includes built-in shell commands, which means that the shell can execute them without reading a separate utility from disk:
  eval
  :
  type

Then you will cover several external commands that exist as binary programs on disk:

  sleep
  find and xargs
  bc and expr
  remsh (sometimes called rsh, rcmd, or remote)

Built-in tools run slightly more efficiently than external programs because they do not need to be read from the disk. Unless you are looping thousands of times, you usually do not need to be concerned if the tool you use is built in or external.

The eval Command

The eval command can be used when you want the shell to reprocess the command line a second time. The basic syntax is

eval any-UNIX-command

Insert the eval command at the start of any UNIX shell command. This is needed when shell special characters are inserted via variable substitution or command substitution (refer to Chapter 8, “Substitution”). For example,

OUTPUT="> out.file"
echo hello $OUTPUT

The OUTPUT variable contains the > sign to redirect standard output to a file called out.file. However, when you try to use the OUTPUT variable in the echo statement, you find there is a problem. This is what appears on the screen when you run this code:

hello > out.file

The output went to the screen, but not to the file because the > sign was not present when the shell first looked for redirection signs in the original command line. You can fix this problem by inserting the eval command at the start of the echo command:

OUTPUT="> out.file"
eval echo hello $OUTPUT

Now when you run this code, it simply returns to the shell prompt without displaying any text on the screen. It does create a file called out.file that contains the word hello and this is the desired result. You might ask: Why is this useful? The answer is that later you can change the initial definition of OUTPUT, and it affects all later lines that start with eval and end with $OUTPUT. For example,

OUTPUT=" >> out.file"

appends to out.file instead of overwriting it.

OUTPUT= causes output to go to the screen instead of to a file.

The eval command is not used frequently in script writing. It is useful for those occasions where you want to compose a shell command line using shell special characters that are contained in variables or produced by command substitution. (Shell special characters were discussed in Chapter 9, “Quoting.”)

The : Command


The : character is actually a complete shell command that does nothing but return a zero completion code, which indicates the command has completed successfully. It can be used as a no-op, which is a command that does nothing and thus can be safely inserted anywhere a command is needed for purely syntactical reasons:
if [ -x $CMD ]
then :
else
   echo Error: $CMD is not executable >&2
fi

In this example, assume you are not quite ready to write the code to follow the then statement. The shell flags a syntax error if you leave that code out completely, so you insert the : command as a temporary no-op command that can be replaced by the desired code later.

Because the : always returns a successful result, it is sometimes used to create an infinite loop:

while :
do
   echo "Enter some input: \c"
   read INPUT
   [ "$INPUT" = stop ] && break
done

Because the : always returns a successful or true result, the while loop will continue forever or until a break is executed within the loop. Sometimes you might find that while true used in place of while : but using the : is more efficient because it is a shell built-in command, whereas true is a command that must be read from a disk file, if you are in the Bourne shell.

You might sometimes find the : used as the first line of a shell script. You sometimes find this in older scripts written when programmers used the C shell but wrote scripts for the Bourne shell. If you start a script from the C shell and the first character of the script is a # sign, it assumes that this script uses C shell syntax, not Bourne shell syntax. Thus it was important to start Bourne shell scripts with something other than a # sign, and the : no-op was often used.

Another use of the : command takes advantage of the fact that the shell evaluates arguments to it. This is a useful way to invoke variable substitution as covered in Chapter 8:

: ${LINES:=24} ${TERM:?"TERM not set"}

The : is a no-op, but the shell still evaluates its arguments. Thus LINES is set to 24 if LINES is empty or undefined. If TERM is empty or undefined, the whole script aborts with the error message “TERM not set”.

The type Command

The type command tells you the full pathname of a given UNIX command.

The basic syntax is

type command1 command2 ...

If the command given is not a utility that exists as a separate disk file, type tells you whether it is one of the following:

  A shell built-in command
  A shell keyword or reserved word
  An alias

If the given command is an alias for another command, type also gives the command that is actually invoked when you run the alias.

For example,

$ type true vi case ulimit history
true is /bin/true
vi is /usr/bin/vi
case is a keyword
ulimit is a shell builtin
history is an exported alias for fc -l
$

Different types of UNIX systems can implement the same command in different ways. For example, true is a shell included on some UNIX systems and in some UNIX shells and therefore is as efficient to use as the : command. You can check whether true is built into your system by using the type command.


Previous Table of Contents Next