Main index

Introducing UNIX and Linux


Introduction to shells

Overview
Why do we need a shell?
Shell syntax
      Types of shell command
      Simple commands
      Pipelines
      Grouping commands
      Exit status
      List commands
Arithmetic
      Operators and functions
Making decisions
      The 'test' statement
            Operators used by 'test'
      The 'if' statement
Loops
      'For' loops
      'While' and 'until' loops
Searching for files
      Arguments to 'find'
Formatted output
      Arguments to 'printf'
Passing information to scripts
      Scripts with arguments
      Parameter expansion
Summary
Exercises

Formatted output

To display messages on standard output we have so far used echo. This command can only write a single string on a single line. A command printf (very similar to printf() in the language C) is provided to format a message any way you desire. Use of printf involves giving it a string, known as the format, as first argument, followed perhaps by subsequent arguments. The format string is copied to the standard output with certain changes made. A simple example is

printf "Hello"
Hello$

Note that Hello is precisely what has been printed - no extra spaces and no Newline character after it, so that the next dollar prompt follows it immediately.

If a \ (backslash) is encountered, it is treated as an escape character with the following character examined, and the pair are replaced by a single character. Not all of these characters will be interpreted sensibly by all terminals, especially formfeed and vertical tab.

Perhaps the most common escape sequence you will meet is \n, to terminate a line:

printf "Hello\nthere\n"
Hello
there

When a % ('percent') is included, the following several characters represent a conversion specification, to instruct how one of the arguments is to be displayed. There should be the same number of conversion specifications as arguments following the format string, and they are paired up with the arguments in order. The next example illustrates the use of %d to insert a number into the output:

printf "%d is a square number\n" 64
64 is a square number

The string %% is not a specification, and is replaced by a single % in the output:

printf "%s is %d%%\n" "one half" 50
one half is 50%

Between the % and the conversion character may come a number indicating the field width in which the argument should be printed, and preceding this number may come a - (hyphen) indicating that the argument should be displayed left-justified within the field (it would by default be right-justified). If the data is numeric, then following the % immediately with a + would cause the number always to be displayed with a leading + or - sign. Note that if you wish printf to terminate a line, you must do so yourself by including a \n within the format string. The following examples illustrate use of printf:

printf "Hello %s\n" $LOGNAME
Hello chris

The string value of LOGNAME is substituted for %s.

printf "The temperature is %+7d degrees\n" 21
The temperature is      +21 degrees

The number 21 is substituted for %d, preceded by a + sign, and padded out with blanks to fill 7 character positions.

printf "You are %s\nyour home directory is: %s\n" \
$( logname ) $HOME

You are chris
your home directory is: /home/ugrad/chris

The string that results from executing the command logname, and the value of the variable HOME, are substituted for the two %s specifications. Note the Newlines within the format string, and the use of a backslash to continue the statement onto another line when it becomes long.

Worked example

Write a script to read the standard input, and display each word from the input, right-justified in one column of width 30. A blank line (or end of file) will terminate the script.
Solution: This is concerned with formatting, so we need printf. Use a while loop to continually read in words until a 'null' one is read in (which happens with a blank line or end of file).

read X                 # Read first word
while [ "$X" ]         # while a "real" word ...
do
  printf "%30s\n" $X   # print it ...
  read X               # and read next one
done

Copyright © 2002 Mike Joy, Stephen Jarvis and Michael Luck