Bookmark this page

Chapter 1.  Improve Command-line Productivity

Abstract

Goal

Run commands more efficiently by using advanced features of the Bash shell, shell scripts, and various Red Hat Enterprise Linux utilities.

Objectives
  • Run commands more efficiently by using advanced features of the Bash shell, shell scripts, and various Red Hat Enterprise Linux utilities.

  • Run repetitive tasks with for loops, evaluate exit codes from commands and scripts, run tests with operators, and create conditional structures with if statements.

  • Create regular expressions to match data, apply regular expressions to text files with the grep command, and use grep to search files and data from piped commands.

Sections
  • Write Simple Bash Scripts (and Guided Exercise)

  • Loops and Conditional Constructs in Scripts (and Guided Exercise)

  • Match Text in Command Output with Regular Expressions (and Guided Exercise)

Lab
  • Improve Command-line Productivity

Write Simple Bash Scripts

Objectives

  • Run commands more efficiently by using advanced features of the Bash shell, shell scripts, and various Red Hat Enterprise Linux utilities.

Create and Execute Bash Shell Scripts

You can accomplish many system administration tasks by using command-line tools. More complex tasks often require chaining together multiple commands that pass results between them. By using the Bash shell environment and scripting features, you can combine Linux commands into shell scripts to solve repetitive real-world problems.

A Bash shell script is an executable file that contains a list of commands, and possibly with programming logic to control decision-making in the overall task. When well-written, a shell script is a powerful command-line tool on its own, and you can use it with other scripts.

Shell scripting proficiency is essential for system administrators in any operational environment. You can use shell scripts to improve the efficiency and accuracy of routine task completion.

Although you can use any text editor, advanced editors such as vim or emacs understand Bash shell syntax and can provide color-coded highlighting. This highlighting helps to identify common scripting errors such as improper syntax, unmatched quotes, parentheses, brackets, and braces, and other structural mistakes.

Specify the Command Interpreter

The first line of a script begins with the #! notation, which is commonly referred to as she-bang or hash-bang, from the names of those two characters, sharp or hash and bang. This notation is an interpreter directive to indicate the command interpreter and command options to process the remaining lines in the file. For Bash syntax script files, the first line is the following directive:

#!/usr/bin/bash

Execute a Bash Shell Script

A shell script file must have execute permissions to run it as an ordinary command. Use the chmod command to modify the file permissions. Use the chown command, if needed, to grant execute permission only for specific users or groups.

If the script is stored in a directory that is listed in the shell's PATH environmental variable, then you can run the shell script by using only its file name, similar to running compiled commands. Because PATH parsing runs the first matching file name that is found, always avoid using existing command names to name your script files. If a script is not in a PATH directory, then run the script by using its absolute path name, which you can determine by querying the file with the which command. Alternatively, run a script in your current working directory by using the . directory prefix, such as ./scriptname.

[user@host ~]$ which hello
~/bin/hello
[user@host ~]$ echo $PATH
/home/user/.local/bin:/home/user/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin

Quote Special Characters

Some characters and words have a special meaning to the Bash shell. To use these characters for their literal values, rather than for their special meanings, you escape them in the script. Use the backslash character (\), single quotes (''), or double quotes ("") to remove (or escape) the special meaning of these characters.

The backslash character removes the special meaning of the single character that immediately follows the backslash. For example, to use the echo command to display the # not a comment literal string, the # hash character must not be interpreted as a comment.

The following example shows the backslash character (\) modifying the hash character so it is not interpreted as a comment:

[user@host ~]$ echo # not a comment

[user@host ~]$ echo \# not a comment
# not a comment

To escape more than one character in a text string, either use the backslash character multiple times, or enclose the whole string in single quotes ('') to interpret literally. Single quotes preserve the literal meaning of all characters that they enclose. Observe the backslash character and single quotes in these examples:

[user@host ~]$ echo # not a comment #

[user@host ~]$ echo \# not a comment #
# not a comment
[user@host ~]$ echo \# not a comment \#
# not a comment #
[user@host ~]$ echo '# not a comment #'
# not a comment #

Use double quotation marks to suppress globbing (file name pattern matching) and shell expansion, but still allow command and variable substitution. Variable substitution is conceptually the same as command substitution, but might use optional brace syntax. Observe the following examples of various quotation mark forms.

Use single quotation marks to interpret all enclosed text literally. Besides suppressing globbing and shell expansion, single quotation marks also direct the shell to suppress command and variable substitution. The question mark (?) is included inside the quotations, because it is a metacharacter that also needs escaping from expansion.

[user@host ~]$ var=$(hostname -s); echo $var
host
[user@host ~]$ echo "***** hostname is ${var} *****"
***** hostname is host *****
[user@host ~]$ echo Your username variable is \$USER.
Your username variable is $USER.
[user@host ~]$ echo "Will variable $var evaluate to $(hostname -s)?"
Will variable host evaluate to host?
[user@host ~]$ echo 'Will variable $var evaluate to $(hostname -s)?'
Will variable $var evaluate to $(hostname -s)?
[user@host ~]$ echo "\"Hello, world\""
"Hello, world"
[user@host ~]$ echo '"Hello, world"'
"Hello, world"

Provide Output from a Shell Script

The echo command displays arbitrary text by passing the text as an argument to the command. By default, the text is sent to standard output (STDOUT). You can send text elsewhere by using output redirection. In the following simple Bash script, the echo command displays the "Hello, world" message to STDOUT, which defaults to the screen device.

[user@host ~]$ cat ~/bin/hello
#!/usr/bin/bash

echo "Hello, world"

[user@host ~]$ hello
Hello, world

Note

This user can run hello at the prompt because the ~/bin (/home/user/bin) directory is in the user's PATH variable and the hello script has executable permission. The PATH parser finds the script first, if no other executable file called hello is found in any earlier PATH directory. Your home directory's bin subdirectory is intended to store your personal scripts.

The echo command is widely used in shell scripts to display informational or error messages. Messages helpfully indicate a script's progress, and can be directed to standard output or standard error, or be redirected to a log file for archiving. When you display error messages, good programming practice is to redirect error messages to STDERR to separate them from normal program output.

[user@host ~]$ cat ~/bin/hello
#!/usr/bin/bash

echo "Hello, world"
echo "ERROR: Houston, we have a problem." >&2

[user@host ~]$ hello 2> hello.log
Hello, world
[user@host ~]$ cat hello.log
ERROR: Houston, we have a problem.

The echo command is also helpful to debug a problematic shell script. Adding echo statements in a script, to display variable values and other runtime information, can help to clarify how a script is behaving.

References

bash(1), echo(1), and echo(1p) man pages

Revision: rh134-9.3-5fd2368