Title graphic

Substitutions - Part 2

In our last lesson, we learned how to create variables and perform substitutions with them. In this lesson, we will extend this idea to show how we can substitute the results from a command.

When we last left our script, it could create an HTML page that contained a few simple lines of text, including the host name of the machine which we obtained from the environment variable HOSTNAME. Next, we will add a timestamp to the page to indicate when it was last updated, along with the user that did it.

#!/bin/bash

# make_page - A script to produce an HTML file

title="System Information for"

cat <<- _EOF_
    <HTML>
    <HEAD>
        <TITLE>
        $title $HOSTNAME
        </TITLE>
    </HEAD>

    <BODY>
    <H1>$title $HOSTNAME</H1>
    <P>Updated on $(date +"%x %r %Z") by $USER
    </BODY>
    </HTML>
_EOF_
       

As you can see, we employed another environment variable, USER, to get the user name. In addition, we used this strange looking thing:

$(date +"%x %r %Z")

The characters "$( )" tell the shell, "substitute the results of the enclosed command." In our script, we want the shell to insert the results of the command date +"%x %r %Z" which expresses the current date and time. The date command has many features and formatting options. To look at them all, try this:

[me@linuxbox me]$ date --help | less

Be aware that there is an older, alternate syntax for "$(command)" that uses the backtick character " ` ". This older form is compatible with the original Bourne shell (sh). I tend not to use the older form since I am teaching bash here, not sh, and besides, I think backticks are ugly. The bash shell fully supports scripts written for sh, so the following forms are equivalent:

$(command)
`command`

--help and other tricks

How do you learn about commands? Well, besides reading about them on LinuxCommand.org, you might try using the man page for the command in question. The SuperMan Pages on LinuxCommand.org contain a complete set for popular Linux distribution. But what if the command doesn't have a man page?

The first thing to try is "--help". All of the tools written by the GNU Project from the Free Software Foundation implement this option. To get a brief list of the command's options, just type:

[me@linuxbox me]$ command --help

Many commands (besides the GNU tools) will either accept the --help option or will consider it an invalid option and will display a usage message which you may find equally useful.

If the results of the --help option scroll off the screen, pipe the results into less to view it like this:

[me@linuxbox me]$ command --help | less

Some commands don't have help messages or don't use --help to invoke them. On these mysterious commands, I use this trick:

First, find out where the executable file is located (this trick will only work with programs, not shell builtins). This is easily done by typing:

[me@linuxbox me]$ which command

The which command will tell you the path and file name of the executable program. Next, use the strings command to display text that may be embedded within the executable file. For example, if you wanted to look inside the bash program, you would do the following:

[me@linuxbox me]$ which bash
/bin/bash
[me@linuxbox me]$
strings /bin/bash

The strings command will display any human readable content buried inside the program. This might include copyright notices, error messages, help text, etc.

Finally, if you have a very inquisitive nature, get the command's source code and read that. Even if you cannot fully understand the programming language in which the command is written, you may be able to gain valuable insight by reading the author's comments in the program's source.

Assigning a command's result to a variable

You can also assign the results of a command to a variable:

right_now=$(date +"%x %r %Z")

You can even nest the variables (place one inside another), like this:

right_now=$(date +"%x %r %Z")
time_stamp="Updated on $right_now by $USER"

Constants

As the name variable suggests, the content of a variable is subject to change. This means that it is expected that during the execution of your script, a variable may have its content modified by something you do.

On the other hand, there may be values that, once set, should never be changed. These are called constants. I bring this up because it is a common idea in programming. Most programming languages have special facilities to support values that are not allowed to change. Bash also has these facilities but, to be honest, I never see it used. Instead, if a value is intended to be a constant, it is simply given an uppercase name. Environment variables are usually considered constants since they are rarely changed. Like constants, environment variables are given uppercase names by convention. In the scripts that follow, I will use this convention - uppercase names for constants and lowercase names for variables.

So with everything we know, our program looks like this:

#!/bin/bash

# make_page - A script to produce an HTML file

TITLE="System Information for $HOSTNAME"
RIGHT_NOW=$(date +"%x %r %Z")
TIME_STAMP="Updated on $RIGHT_NOW by $USER"

cat <<- _EOF_
    <HTML>
    <HEAD>
        <TITLE>
        $TITLE
        </TITLE>
    </HEAD>

    <BODY>
    <H1>$TITLE</H1>
    <P>$TIME_STAMP
    </BODY>
    </HTML>
_EOF_
       

© 2000-2014, William E. Shotts, Jr. Verbatim copying and distribution of this entire article is permitted in any medium, provided this copyright notice is preserved.

Linux® is a registered trademark of Linus Torvalds.