Mastering Unix Shell Scripting - Randal K. Michael - E-Book

Mastering Unix Shell Scripting E-Book

Randal K. Michael

0,0
57,99 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

UNIX expert Randal K. Michael guides you through every detail of writing shell scripts to automate specific tasks. Each chapter begins with a typical, everyday UNIX challenge, then shows you how to take basic syntax and turn it into a shell scripting solution. Covering Bash, Bourne, and Korn shell scripting, this updated edition provides complete shell scripts plus detailed descriptions of each part. UNIX programmers and system administrators can tailor these to build tools that monitor for specific system events and situations, building solid UNIX shell scripting skills to solve real-world system administration problems.

Sie lesen das E-Book in den Legimi-Apps auf:

Android
iOS
von Legimi
zertifizierten E-Readern

Seitenzahl: 1364

Veröffentlichungsjahr: 2011

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Table of Contents

Title Page

Copyright

Dedication

About the Author

Credits

Acknowledgments

Introduction

Overview of the Book and Technology

How This Book Is Organized

Who Should Read this Book

Tools You Will Need

What's on the Web Site

Summary

Part I: The Basics of Shell Scripting

Chapter 1: Scripting Quick Start and Review

Case Sensitivity

UNIX Special Characters

Shells

Shell Scripts

Functions

Running a Shell Script

Comments and Style in Shell Scripts

Control Structures

Using break, continue, exit, and return

Here Document

Shell Script Commands

Symbol Commands

Variables

Command-Line Arguments

shift Command

Special Parameters $* and $@

Double Quotes, Forward Tics, and Back Tics

Using awk on Solaris

Using the echo Command Correctly

Math in a Shell Script

Built-In Mathematical Functions

File Permissions, suid and sgid Programs

Running Commands on a Remote Host

Setting Traps

User-Information Commands

ps Command

Communicating with Users

Uppercase or Lowercase Text for Easy Testing

Check the Return Code

Time-Based Script Execution

Output Control

Catching a Delayed Command Output

Fastest Ways to Process a File Line-by-Line

Using Command Output in a Loop

Mail Notification Techniques

Creating a Progress Indicator

Working with Record Files

Creating a Pseudo-Random Number

Checking for Stale Disk Partitions in AIX

Automated Host Pinging

Highlighting Specific Text in a File

Keeping the Printers Printing

Automated FTP File Transfer

Using rsync to Replicate Data

Capturing a List of Files Larger than $MEG

Capturing a User's Keystrokes

Using the bc Utility for Floating-Point Math

Number Base Conversions

Create a Menu with the select Command

Removing Repeated Lines in a File

Removing Blank Lines from a File

Testing for a Null Variable

Directly Access the Value of the Last Positional Parameter, $#

Remove the Column Headings in a Command Output

Arrays

Testing a String

Summary

Chapter 2: 24 Ways to Process a File Line-by-Line

Command Syntax

24 Methods to Parse a File Line-by-Line

Timing Each Method

What about Using Command Input Instead of File Input?

Summary

Lab Assignments

Chapter 3: Automated Event Notification

Basics of Automating Event Notification

Problems with Outbound Mail

Dial-Out Modem Software

SNMP Traps

Summary

Lab Assignments

Chapter 4: Progress Indicators Using a Series of Dots, a Rotating Line, or Elapsed Time

Indicating Progress with a Series of Dots

Indicating Progress with a Rotating Line

Indicating Progress with Elapsed Time

Combining Feedback Methods

Other Options to Consider

Summary

Lab Assignments

Part II: Scripts for Programmers, Testers, and Analysts

Chapter 5: Working with Record Files

What Is a Record File?

Processing the Record Files

Tasks for Records and Record Files

The Merge Process

Putting It All Together

Other Things to Consider

Summary

Lab Assignments

Chapter 6: Automated FTP Stuff

Syntax

Automating File Transfers and Remote Directory Listings

What about Encryption?

Other Things to Consider

Summary

Lab Assignments

Chapter 7: Using rsync to Efficiently Replicate Data

Syntax

Generic rsync Shell Script

Replicating Multiple Directories with rsync

Replicating Multiple Filesystems with rsync

Replicating an Oracle Database with rsync

rsync Copy Shell Script

Chapter 8: Automating Interactive Programs with Expect and Autoexpect

Downloading and Installing Expect

The Basics of Talking to an Interactive Script or Program

Using autoexpect to Automatically Create an Expect Script

Working with Variables

What about Conditional Tests?

Using Expect Scripts with Sun Blade Chassis and JumpStart

Summary

Lab Assignments

Chapter 9: Finding Large Files and Files of a Specific Type

Syntax

Remember That File and Directory Permissions Thing

Don't Be Shocked by the Size of the Files

Creating the Script

Other Options to Consider

Summary

Lab Assignments

Chapter 10: Process Monitoring and Enabling Pre-Processing, Startup, and Post-Processing Events

Syntax

Monitoring for a Process to Start

Monitoring for a Process to End

Monitor and Log as a Process Starts and Stops

Timed Execution for Process Monitoring, Showing Each PID, and Timestamp with Event and Timing Capability

Other Options to Consider

Summary

Lab Assignments

Chapter 11: Pseudo-Random Number and Data Generation

What Makes a Random Number?

The Methods

Shell Script to Create Pseudo-Random Numbers

Creating Unique Filenames

Creating a File Filled with Random Characters

Other Things to Consider

Summary

Lab Assignments

Chapter 12: Creating Pseudo-Random Passwords

Randomness

Creating Pseudo-Random Passwords

Syntax

Building the Password-Creation Script

Other Options to Consider

Summary

Lab Assignments

Chapter 13: Floating-Point Math and the bc Utility

Syntax

Creating Some Shell Scripts Using bc

Other Options to Consider

Summary

Lab Assignments

Chapter 14: Number Base Conversions

Syntax

Scripting the Solution

An Easy, Interactive Script to Convert Between Bases

Using the bc Utility for Number Base Conversions

Other Options to Consider

Summary

Lab Assignments

Chapter 15: hgrep: Highlighted grep Script

Reverse Video Control

Building the hgrep.bash Shell Script

Other Options to Consider

Summary

Lab Assignments

Chapter 16: Monitoring Processes and Applications

Monitoring Local Processes

Remote Monitoring with Secure Shell and Remote Shell

What about Waiting for Something to Complete Executing?

Other Things to Consider

Summary

Lab Assignments

Part III: Scripts for Systems Administrators

Chapter 17: Filesystem Monitoring

Syntax

Adding Exceptions Capability to Monitoring

Using the MB-of-Free-Space Method

Using MB of Free Space with Exceptions

Percentage Used—MB Free and Large Filesystems

Running Filesystem Scripts on AIX, Linux, HP-UX, OpenBSD, and Solaris

Other Options to Consider

Summary

Lab Assignments

Chapter 18: Monitoring Paging and Swap Space

Syntax

Creating the Shell Scripts

Other Options to Consider

Summary

Lab Assignments

Chapter 19: Monitoring System Load

Installing the System-Statistics Programs in Linux

Syntax

Scripting the Solutions

Other Options to Consider

Summary

Lab Assignments

Chapter 20: Monitoring for Stale Disk Partitions (AIX-Specific)

AIX Logical Volume Manager (LVM)

The Commands and Methods

Other Options to Consider

Summary

Lab Assignment

Chapter 21: Turning On/Off SSA Identification Lights

Syntax

The Scripting Process

Other Things to Consider

Summary

Lab Assignment

Chapter 22: Automated Hosts Pinging with Notification of Failure

Syntax

Creating the Shell Script

Other Options to Consider

Summary

Lab Assignments

Chapter 23: Creating a System-Configuration Snapshot

Syntax

Creating the Shell Script

Other Options to Consider

Summary

Lab Assignment

Chapter 24: Compiling, Installing, Configuring, and Using sudo

The Need for sudo

Configuring sudo on Solaris

Downloading and Compiling sudo

Compiling sudo

Configuring sudo

Using sudo

Using sudo in a Shell Script

Logging to the syslog with sudo

The sudo Log File

Summary

Lab Assignments

Chapter 25: Print-Queue Hell: Keeping the Printers Printing

System V versus BSD versus CUPS Printer Systems

Putting It All Together

Other Options to Consider

Summary

Lab Assignments

Chapter 26: Those Pesky Sarbanes-Oxley (SOX) Audits

What to Expect

How to Work with the Auditors

What the Auditors Want to See

Some Handy Commands

Using the dirname and basename Commands

Other Things to Consider

Summary

Lab Assignments

Chapter 27: Using Dirvish with rsync to Create Snapshot-Type Backups

How Does Dirvish Work?

Configuring Dirvish

Performing a Full System Backup

Using Dirvish on the Command Line

A Menu-Interface Shell Script to Control Dirvish

Putting It All Together

Using the dirvish_ctrl Shell Script

Other Things to Consider

Summary

Lab Assignments

Chapter 28: Monitoring and Auditing User Keystrokes

Syntax

Scripting the Solution

Other Options to Consider

Summary

Lab Assignments

A Closing Note from the Author

Appendix A: What's on the Web Site

Shell Scripts

Functions

Index

Mastering UNIX® Shell Scripting: Bash, Bourne, and Korn Shell Scripting for Programmers, System Administrators, and UNIX Gurus, Second Edition

Published by

Wiley Publishing, Inc.

10475 Crosspoint Boulevard

Indianapolis, IN 46256

www.wiley.com

Copyright © 2008 by Randal K. Michael

Published by Wiley Publishing, Inc., Indianapolis, Indiana

Published simultaneously in Canada

ISBN: 978-0-470-18301-4

No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, scanning or otherwise, except as permitted under Sections 107 or 108 of the 1976 United States Copyright Act, without either the prior written permission of the Publisher, or authorization through payment of the appropriate per-copy fee to the Copyright Clearance Center, 222 Rosewood Drive, Danvers, MA 01923, (978) 750-8400, fax (978) 646-8600. Requests to the Publisher for permission should be addressed to the Legal Department, Wiley Publishing, Inc., 10475 Crosspoint Blvd., Indianapolis, IN 46256, (317) 572-3447, fax (317) 572-4355, or online at http://www.wiley.com/go/permissions.

Limit of Liability/Disclaimer of Warranty: The publisher and the author make no representations or warranties with respect to the accuracy or completeness of the contents of this work and specifically disclaim all warranties, including without limitation warranties of fitness for a particular purpose. No warranty may be created or extended by sales or promotional materials. The advice and strategies contained herein may not be suitable for every situation. This work is sold with the understanding that the publisher is not engaged in rendering legal, accounting, or other professional services. If professional assistance is required, the services of a competent professional person should be sought. Neither the publisher nor the author shall be liable for damages arising herefrom. The fact that an organization or Website is referred to in this work as a citation and/or a potential source of further information does not mean that the author or the publisher endorses the information the organization or Website may provide or recommendations it may make. Further, readers should be aware that Internet Websites listed in this work may have changed or disappeared between when this work was written and when it is read.

For general information on our other products and services or to obtain technical support, please contact our Customer Care Department within the U.S. at (800) 762-2974, outside the U.S. at (317) 572-3993 or fax (317) 572-4002.

Library of Congress Cataloging-in-Publication Data is available from publisher.

Trademarks: Wiley, the Wiley logo, and related trade dress are trademarks or registered trademarks of John Wiley & Sons, Inc. and/or its affiliates, in the United States and other countries, and may not be used without written permission. UNIX is a registered trademark of The Open Group. All other trademarks are the property of their respective owners. Wiley Publishing, Inc., is not associated with any product or vendor mentioned in this book.

Wiley also publishes its books in a variety of electronic formats. Some content that appears in print may not be available in electronic books.

This book is dedicated to my wife Robin, the girls, Andrea and Ana, and the grandchildren, Gavin, Jocelyn, and Julia—my true inspiration.

About the Author

Randal K. Michael is a UNIX Systems Administrator working as a contract consultant. He teaches UNIX shell scripting in corporate settings, where he writes shell scripts to address a variety of complex problems and tasks, ranging from monitoring systems to replicating large databases. He has more than 30 years of experience in the industry and 15 years of experience as a UNIX Systems Administrator, working on AIX, HP-UX, Linux, OpenBSD, and Solaris.

Credits

Executive Editor

Carol Long

Development Editor

John Sleeva

Technical Editor

John Kennedy

Production Editor

Dassi Zeidel

Copy Editor

Kim Cofer

Editorial Manager

Mary Beth Wakefield

Production Manager

Tim Tate

Vice President and Executive Group Publisher

Richard Swadley

Vice President and Executive Publisher

Joseph B. Wikert

Project Coordinator, Cover

Lynsey Stanford

Proofreader

Candace English

Indexer

Robert Swanson

Acknowledgments

The information that I gathered together in this book is the result of working with some of the most talented UNIX professionals on the topic. I have enjoyed every minute of my association with these UNIX gurus and it has been my pleasure to have the opportunity to gain so much knowledge from the pros. I want to thank every one of these people for asking and answering questions over the past 20 years. If my brother Jim had not kept telling me, “you should write a book,” after querying me for UNIX details on almost a weekly basis, I doubt the first edition of this book would have ever been written.

I especially want to thank Jack Renfro at Chrysler Corporation for giving me my first shell scripting project so long ago. I had to start with the man pages, but that is how I learned to dig deep to get the answer. Since then I have been on a mission to automate, through shell scripting, support tasks on every system I come in contact with. I certainly value the years I was able to work with Jack.

I must also thank the talented people at Wiley Publishing. As executive editor, Carol Long helped keep things going smoothly. Development editor John Sleeva kept me on schedule and made the edits that make my writing flow with ease. Dassi Zeidel, my production editor, helped with the final edits and prepared the book for layout. John Kennedy, my technical editor, kept me honest, gave me some tips, and ensured the code did not have any errors. It has been a valuable experience for me to work with such a fine group of professionals at Wiley Publishing. I also want to thank my agent, Carole McClendon, at Waterside Productions for all her support on this project. Carole is the best agent that anyone could ever ask for. She is a true professional with the highest ethics.

Of course, my family had a lot to do with my success on this and every project. I want to thank Mom, Pop, Gene, Jim, Marcia, Rusty, Mallory, Anica, and Chad. I want to thank my beautiful bride forever, Robin, for her understanding, patience, and support for the long hours required to complete this project. The girls, Andrea and Ana, always keep a smile on my face, and Steve is always on my mind. The grandchildren, Gavin, Jocelyn, and Julia, are an inspiration for long life, play time, learning, and adventure. I am truly living the dream.

I could not have written this book without the support of all these people and the many others that remain unnamed. It has been an honor!

Introduction

In UNIX there are many ways to accomplish the same task. Given a problem to solve, we may be able to get to a solution in any number of ways. Of course, some techniques will be more efficient, use fewer system resources, and may or may not give the user feedback on what is going on or give more accurate details and more precision to the result. In this book we are going to step through every detail of creating shell scripts to solve real-world UNIX problems and tasks. The shell scripts range from using a pseudo-random number generator to creating passwords using arrays to replicating data with rsync to working with record files. The scope of solutions is broad and detailed. The details required to write a good shell script include commenting each step for future reference. Other details include combining many commands together into a single command statement when desirable, separating commands on several lines of code when readability and understanding the concept may be diminished, and making a script readable and easy to maintain through the life cycle. We will see the benefits of variables and files to store data, show methods to strip out unneeded data from command output, and format data for a particular purpose. Additionally, we are going to show how to write and use functions in our shell scripts and demonstrate the benefits of functions over a shell script written without functions.

This book is intended for any flavor of UNIX, but it emphasizes the AIX, HP-UX, Linux, OpenBSD, and Solaris operating systems. Almost every script in the book is also included on the book's companion web site (www.wiley.com/go/michael2e). Many of the shell scripts are rewritten for various UNIX flavors, when it is necessary. Other shell scripts are not platform-dependent. These script rewrites are necessary because command syntax and output vary, sometimes in a major way, between UNIX flavors. The variations are sometimes as small as extracting data out of a different column or using a different command switch to get the same result, or they can be as major as putting several commands together to accomplish the same task and get a similar output or result on different flavors of UNIX.

In each chapter we start with the very basic concepts to accomplish a task, and then work our way up to some very complex and difficult concepts. The primary purpose of a shell script is to automate repetitive and complex tasks. This alleviates keystroke errors and allows for time-scheduled execution of the shell scripts. It is always better to have the system tell us that it has a problem than to find out too late to be proactive. This book will help us to be more proactive and efficient in our dealing with the system. At every level you will gain more knowledge to allow you to move on to ever increasingly complex ideas with ease. You are going to see different ways to solve real-world example tasks. There is not just one way to solve a challenge, and we are going to look at the pros and cons of attacking a problem in various ways. Our goal is to be confident and flexible problem solvers. Given a task, we can solve it in any number of ways, and the solution will be intuitively obvious when you complete this book.

Overview of the Book and Technology

This book is intended as a learning tool and study guide to learn how to write shell scripts to solve a multitude of problems by starting with a clear goal. We will cover most shell scripting techniques about seven times, each time hitting the topic from a different angle, solving a different problem. I have found this technique to work extremely well for retention of the material.

Each chapter ends with Lab Assignments that let you either write a new script or modify a shell script covered in the chapter. There is not a “solutions” book. The solution is to make it work! I urge everyone to read this book from cover to cover to get the maximum benefit. The shells covered in this book include Bash, Bourne, and Korn. C shell is not covered. Advanced topics include using rsync to replicate data, creating snapshot-style backups utilizing Dirvish, working with record files to parse data, and many others.

This book goes from some trivial task solutions to some rather advanced concepts that everyone from high school and college students to Systems Administrators will benefit from, and a lot in between. There are several chapters at each level of complexity scattered throughout the book. The shell scripts presented in this book are complete shell scripts, which is one of the things that sets this book apart from other shell-scripting books on the market. The solutions are explained thoroughly, with each part of the shell scripts explained in minute detail down to the philosophy and mindset of the author.

How This Book Is Organized

Each chapter starts with a typical UNIX challenge that occurs every day in the computer world. With each challenge we define a specific goal and start the shell script by defining the correct command syntax to solve the problem. After we present the goal and command syntax, we start by building the shell script around the commands. The next step is to filter the commands' output to strip out the unneeded data, or we may decide to just extract the data we need from the output. If the syntax varies between UNIX flavors, we show the correct syntax to get the same or a similar result. When we get to this point we go further to build options into the shell script to give the end user more flexibility on the command line.

When a shell script has to be rewritten for each operating system, a combined shell script is shown at the end of the chapter that will run on all the UNIX flavors studied in this book, except where noted. To do this last step, we query the system for the UNIX flavor using the uname command. By knowing the flavor of the operating system, we are able to execute the proper commands for each UNIX flavor by using a simple case statement. If this is new to you, don't worry; everything is explained in detail throughout the book.

Each chapter targets a different real-world problem. Some challenges are very complex, whereas others are just interesting to play around with. Some chapters hit the problem from several different angles in a single chapter, and others leave you the challenge to solve on your own—of course, with a few hints to get you started. Each chapter solves the challenge presented and can be read as a single unit without referencing other chapters in the book, except where noted. Some of the material, though, is explained in great detail in one chapter and lightly covered in other chapters. Because of this variation, I recommend that you start at the beginning of the book and read and study every chapter, and solve each of the Lab Assignments through to the end of the book, because this is a learning experience!

Who Should Read this Book

This book is intended for anyone who works with UNIX from the command line on a daily basis. The topics covered in this book are mainly for UNIX professionals—computer science students, programmers, programmer-analysts, Systems Operators, application support personnel, Systems Administrators, and anyone who is interested in getting ahead in the support and development arenas. Beginners will get a lot out of this book, too, although some of the material may be a little high-level, so a basic UNIX book may be needed to answer some questions. Everyone should have a good working knowledge of common UNIX commands before starting this book; we do not explain basic UNIX commands in much detail.

I started my career in UNIX by learning on the job how to be a Systems Operator. I wish I had a book like this when I started. Having this history, I wanted others to get a jump-start on their careers. I wrote this book with the knowledge that I was in your shoes at one time, and I remember that I had to learn everything from the man pages, one command at a time. Use this book as a study guide, and you will have a jump-start to get ahead quickly in the UNIX world, which is getting bigger all the time.

Tools You Will Need

To get the most benefit from this book you need access to a UNIX machine, preferably with AIX, HP-UX, Linux, OpenBSD, or Solaris installed. You can run Linux, Solaris, and OpenBSD on standard PC hardware, and this is relatively inexpensive, if not free. Your default shell should be set to Bash or Korn shell. You can find your default shell by entering echo $SHELL on the command line. None of the shell scripts in this book requires a graphical terminal, but it does not hurt to have Gnome, CDE, KDE, or X-Windows running. This way you can work in multiple windows at the same time and cut and paste code between windows.

You also need a text editor that you are comfortable using. UNIX operating systems come with the vi editor, and many include emacs. You can also use the text editor that comes with KDE, CDE, and Gnome. Remember that the editor must be a text editor that stores files in a standard ANSII format. You will also need some time, patience, and an open, creative mind that is ready to learn.

Another thing to note is that all of the variables used in the shell scripts and functions in this book are in uppercase characters. I did this because it is much easier to follow along with the shell script if you know quickly where the variables are located in the code. When you write your own shell scripts, please use lowercase for all shell script and function variables. The reason this is important is that the operating system, and applications, use environment variables that are uppercase. If you are not careful, you can overwrite a critical system or application variable with your own value and hose the system; however, this is dependent on the scope of where the variable is in the code. Just a word of warning: be careful with uppercase variables!

What's on the Web Site

On the book's companion web site, www.wiley.com/go/michael2e, all the shell scripts and most of the functions that are studied in the book can be found. The functions are easy to cut and paste directly into your own shell scripts to make the scripting process a little easier. Additionally, there is a shell script stub that you can copy to another filename. This script stub has everything to get started writing quickly. The only thing you need to do is fill in the fields for the following: Script Name, Author, Date, Version, Platform, and Rev. List, when revisions are made. There is a place to define variables and functions, and then you have the “BEGINNING OF MAIN” section to start the main body of the shell script.

Summary

This book is for learning how to be creative, proactive, and professional problem solvers. Given a task, the solution will be intuitively obvious to you on completion of this book. This book will help you attack problems logically and present you with a technique of building on what you know. With each challenge presented you will see how to take basic syntax and turn it into the basis for a shell scripting solution. We always start with the basics and build more and more logic into the solution before we add additional options the end user can use for more flexibility.

Speaking of end users, we must always keep our users informed about how processing is proceeding. Giving the user a blank screen to look at is the worst thing that you can do, so for this we can create progress indicators. You will learn how to be proactive by building tools that monitor for specific system events and situations that indicate the beginning stages of an upcoming problem. This is where knowing how to query the system puts you ahead of the game.

With the techniques presented in this book, you will learn. You will learn about problem resolution. You will learn about starting with what you know about a situation and building a solution effectively. You will learn how to make a single shell script work on other platforms without further modifications. You will learn how to be proactive. You will learn how to use plenty of comments in a shell script. You will learn how to write a shell script that is easy to read and follow through the logic. Basically, you will learn to be an effective problem solver, and the solution to any challenge will be intuitively obvious!

Part I

The Basics of Shell Scripting

Chapter 1: Scripting Quick Start and Review

Chapter 2: 24 Ways to Process a File Line-by-Line

Chapter 3: Automated Event Notification

Chapter 4: Progress Indicators Using a Series of Dots, a Rotating Line, or Elapsed Time

Chapter 1

Scripting Quick Start and Review

We are going to start out by giving a targeted refresher course. The topics that follow are short explanations of techniques that we always have to search the book to find; here they are all together in one place. The explanations range from showing the fastest way to process a file line-by-line to the simple matter of case sensitivity of UNIX and shell scripts. This should not be considered a full and complete list of scripting topics, but it is a very good starting point and it does point out a sample of the topics covered in the book. For each topic listed in this chapter there is a very detailed explanation later in the book.

We urge everyone to study this entire book. Every chapter hits a different topic using a different approach. The book is written this way to emphasize that there is never only one technique to solve a challenge in UNIX. All the shell scripts in this book are real-world examples of how to solve a problem. Thumb through the chapters, and you can see that we tried to hit most of the common (and some uncommon!) tasks in UNIX. All the shell scripts have a good explanation of the thinking process, and we always start out with the correct command syntax for the shell script targeting a specific goal. I hope you enjoy this book as much as I enjoyed writing it. Let's get started!

Case Sensitivity

UNIX is case sensitive. Because UNIX is case sensitive, our shell scripts are also case sensitive.

UNIX Special Characters

All of the following characters have a special meaning or function. If they are used in a way that their special meaning is not needed, they must be escaped. To escape, or remove its special function, the character must be immediately preceded with a backslash, \, or enclosed within ’ ’forward tic marks (single quotes).

\ / ; , . ∼ # $ ? & * ( ) [ ] ‘ ‘ “ + - ! ∧ = | < >

Shells

A shell is an environment in which we can run our commands, programs, and shell scripts. There are different flavors of shells, just as there are different flavors of operating systems. Each flavor of shell has its own set of recognized commands and functions. This book works with the Bourne, Bash, and Korn shells. Shells are located in either the /usr/bin/ directory or the /bin/ directory, depending on the UNIX flavor and specific version.

ShellDirectoryBourne/bin/sh or /usr/bin/shBash/bin/bash or /usr/bin/bashKorn/bin/ksh or /usr/bin/ksh

Shell Scripts

The basic concept of a shell script is a list of commands, which are listed in the order of execution. A good shell script will have comments, preceded by a pound sign or hash mark, #, describing the steps. There are conditional tests, such as value A is greater than value B, loops allowing us to go through massive amounts of data, files to read and store data, variables to read and store data, and the script may include functions.

We are going to write a lot of scripts in the next several hundred pages, and we should always start with a clear goal in mind. With a clear goal, we have a specific purpose for the script, and we have a set of expected results. We will also hit on some tips, tricks, and, of course, the gotchas in solving a challenge one way as opposed to another to get the same result. All techniques are not created equal.

Shell scripts and functions are both interpreted. This means they are not compiled. Both shell scripts and functions are ASCII text that is read by the shell command interpreter. When we execute a shell script, or function, a command interpreter goes through the ASCII text line-by-line, loop-by-loop, test-by-test, and executes each statement as each line is reached from the top to the bottom.

Functions

A function is written in much the same way as a shell script but is different in that it is defined, or written, within a shell script most of the time, and is called within the script. This way we can write a piece of code, which is used over and over, just once and use it without having to rewrite the code every time. We just call the function instead.

We can also define functions at the system level that is always available in our environment, but this is a topic for later discussion.

A function has the following form:

functionfunction_name

{

     commands to execute

}

or

function_name ()

{

     commands to execute

}

When we write functions into our scripts we must remember to declare, or write, the function before we use it. The function must appear above the command statement calling the function. We can't use something that does not yet exist.

Running a Shell Script

A shell script can be executed in the following ways:

ksh  shell_script_name

will create a Korn shell and execute the shell_script_name in the newly created Korn shell environment. The same is true for sh and bash shells.

shell_script_name

will execute shell_script_nameif the execution bit is set on the file (see the manual page on the chmod command, man chmod). The script will execute in the shell that is declared on the first line of the shell script. If no shell is declared on the first line of the shell script, it will execute in the default shell, which is the user's system-defined shell. Executing in an unintended shell may result in a failure and give unpredictable results.

Declare the Shell in the Shell Script

Declare the shell! If we want to have complete control over how a shell script is going to run and in which shell it is to execute, we must declare the shell in the first line of the script. If no shell is declared, the script will execute in the default shell, defined by the system for the user executing the shell script. If the script was written, for example, to execute in Bash shell, bash, and the default shell for the user executing the shell script is the C shell, csh, the script will most likely have a failure during execution. To declare a shell, one of the declaration statements in Table 1-2 must appear on the first line of the shell script.

Table 1-2 Different Types of Shells to Declare

CommandDescription#!/bin/sh or #!/usr/bin/shDeclares a Bourne shell#!/bin/ksh or #!/usr/bin/kshDeclares a Korn shell#!/bin/csh or #!/usr/bin/cshDeclares a C shell#!/bin/bash or #!/usr/bin/bashDeclares a Bourne-Again (Bash) shell

Comments and Style in Shell Scripts

Making good comments in our scripts is stressed throughout this book. What is intuitively obvious to us may be total Greek to others who follow in our footsteps. We have to write code that is readable and has an easy flow. This involves writing a script that is easy to read and easy to maintain, which means that it must have plenty of comments describing the steps. For the most part, the person who writes the shell script is not the one who has to maintain it. There is nothing worse than having to hack through someone else's code that has no comments to find out what each step is supposed to do. It can be tough enough to modify the script in the first place, but having to figure out the mindset of the author of the script will sometimes make us think about rewriting the entire shell script from scratch. We can avoid this by writing a clearly readable script and inserting plenty of comments describing what our philosophy is and how we are using the input, output, variables, and files.

For good style in our command statements, we need it to be readable. For this reason it is sometimes better, for instance, to separate a command statement onto three separate lines instead of stringing, or piping, everything together on the same line of code; it may be just too difficult to follow the pipe and understand what the expected result should be for a new script writer. However, in some cases it is more desirable to create a long pipe. But, again, it should have comments describing our thinking step by step. This way someone later will look at our code and say, “Hey, now that's a groovy way to do that.”

Command readability and step-by-step comments are just the very basics of a well-written script. Using a lot of comments will make our life much easier when we have to come back to the code after not looking at it for six months, and believe me; we will look at the code again. Comment everything! This includes, but is not limited to, describing what our variables and files are used for, describing what loops are doing, describing each test, maybe including expected results and how we are manipulating the data and the many data fields. A hash mark, #, precedes each line of a comment.

The script stub that follows is on this book's companion web site at www.wiley.com/go/michael2e. The name is script.stub. It has all the comments ready to get started writing a shell script. The script.stub file can be copied to a new filename. Edit the new filename, and start writing code. The script.stub file is shown in Listing 1-1.

Listing 1-1: script.stub shell script starter listing

#!/bin/bash

#

# SCRIPT: NAME_of_SCRIPT

# AUTHOR: AUTHORS_NAME

# DATE:   DATE_of_CREATION

# REV:    1.1.A (Valid are A, B, D, T and P)

#               (For Alpha, Beta, Dev, Test and Production)

#

# PLATFORM: (SPECIFY: AIX, HP-UX, Linux, OpenBSD, Solaris

#                      or Not platform dependent)

#

# PURPOSE: Give a clear, and if necessary, long, description of the

#          purpose of the shell script. This will also help you stay

#          focused on the task at hand.

#

# REV LIST:

#        DATE: DATE_of_REVISION

#        BY:   AUTHOR_of_MODIFICATION

#        MODIFICATION: Describe what was modified, new features, etc--

#

#

# set -n   # Uncomment to check script syntax, without execution.

#          # NOTE: Do not forget to put the comment back in or

#          #       the shell script will not execute!

# set -x   # Uncomment to debug this shell script

#

##########################################################

#         DEFINE FILES AND VARIABLES HERE

##########################################################

##########################################################

#              DEFINE FUNCTIONS HERE

##########################################################

##########################################################

#               BEGINNING OF MAIN

##########################################################

# End of script

The shell script starter shown in Listing 1-1 gives you the framework to start writing the shell script with sections to declare variables and files, create functions, and write the final section, BEGINNINGOFMAIN, where the main body of the shell script is written.

Control Structures

The following control structures will be used extensively.

if … then statement

     if [ test_command ]

     then

             commands

     fi

if … then … else statement

     if [ test_command ]

     then

          commands

     else

          commands

     fi

if … then … elif … (else) statement

     if  [ test_command ]

     then

          commands

     elif [ test_command ]

     then

          commands

     elif [ test_command ]

     then

           commands

     .

     .

     .

     else     (Optional)

          commands

     fi

for … in statement

     for loop_variable in argument_list

     do

          commands

     done

while statement

     while test_condition_is_true

     do

          commands

     done

until statement

     until  test_condition_is_true

     do

          commands

     done

case statement

     case $variable  in

     match_1)

commands_to_execute_for_1

             ;;

     match_2)

commands_to_execute_for_2

             ;;

     match_3)

commands_to_execute_for_3

             ;;

    .

    .

    .

     *)      (Optional - any other value)

commands_to_execute_for_no_match

             ;;

esac

Note

The last part of the case statement, shown here,

          *)

               commands_to_execute_for_no_match

     ;;

is optional.

Using break, continue, exit, and return

It is sometimes necessary to break out of a for or while loop, continue in the next block of code, exit completely out of the script, or return a function's result back to the script that called the function.

The break command is used to terminate the execution of the entire loop, after completing the execution of all the lines of code up to the break statement. It then steps down to the code following the end of the loop.The continue command is used to transfer control to the next set of code, but it continues execution of the loop.The exit command will do just what one would expect: it exits the entire script. An integer may be added to an exit command (for example, exit0), which will be sent as the return code.The return command is used in a function to send data back, or return a result or return code, to the calling script.

Here Document

A here document is used to redirect input into an interactive shell script or program. We can run an interactive program within a shell script without user action by supplying the required input for the interactive program, or interactive shell script. This is why it is called a here document: the required input is here, as opposed to somewhere else.

This is the syntax for a here document:

program_name <<LABEL

Program_Input_1

Program_Input_2

Program_Input_3

Program_Input_#

LABEL

Example:

/usr/local/bin/My_program << EOF

Randy

Robin

Rusty

Jim

EOF

Notice in the here documents that there are no spaces in the program input lines, between the two EOF labels. If a space is added to the input, the here document may fail. The input that is supplied must be the exact data that the program is expecting, and many programs will fail if spaces are added to the input.

Shell Script Commands

The basis for the shell script is the automation of a series of commands. We can execute most any command in a shell script that we can execute from the command line. (One exception is trying to set an execution suid or sgid, sticky bit, within a shell script; it is not supported for security reasons.) For commands that are executed often, we reduce errors by putting the commands in a shell script. We will eliminate typos and missed device definitions, and we can do conditional tests that can ensure there are not any failures due to unexpected input or output. Commands and command structure will be covered extensively throughout this book.

Most of the commands shown in Table 1-3 are used at some point in this book, depending on the task we are working on in each chapter.

Table 1-3 UNIX Commands Review

CommandDescriptionpasswdChanges user passwordpwdPrints current directorycdChanges directorylsLists files in a directorywildcards* matches any number of characters; ? matches a single characterfilePrints the type of filecatDisplays the contents of a fileprDisplays the contents of a filepg or pageDisplays the contents of a file one page at a timemoreDisplays the contents of a file one page at a timeclearClears the screencp or copyCopies a filechownChanges the owner of a filechgrpChanges the group of a filechmodChanges file modes, permissionsrmRemoves a file from the systemmvRenames a filemkdirCreates a directoryrmdirRemoves a directorygrepPattern matchingegrepgrep command for extended regular expressionsfindLocates files and directories>>Appends to the end of a file > Redirects, creates, or overwrites a file|Strings commands together, known as a pipe||Logical OR—command1 || command2—execute command2 if command1 fails&Executes in background&&Logical AND—command1 && command2—execute command2 if command1 succeedsdateDisplays the system date and timeechoWrites strings to standard outputsleepHalts execution for the specified number of secondswcCounts the number of words, lines, and characters in a fileheadViews the top of a filetailViews the end of a filediffCompares two filessdiffCompares two files side by side (requires 132-character display)spellSpell checkerlp, lpr, enq, qprtPrints a filelpstatStatus of system print queuesenableEnables, or starts, a print queuedisableDisables, or stops, a print queuecalDisplays a calendarwhoDisplays information about users on the systemwExtended who commandwhoamiDisplays $LOGNAME or $USER environment parameterswho am IDisplays login name, terminal, login date/time, and where logged inf, fingerDisplays information about logged-in users, including the users .plan and .projecttalkEnables two users to have a split-screen conversationwriteDisplays a message on a user's screenwallDisplays a message on all logged-in users' screensrwallDisplays a message to all users on a remote hostrsh or remshExecutes a command, or login, on a remote hostdfDisplays filesystem statisticspsDisplays information on currently running processesnetstatShows network statusvmstatShows virtual memory statusiostatShows input/output statusunameShows name of the current operating system, as well as machine informationsarReports system activitybasenameDisplays base filename of a string parametermanDisplays the online reference manualsuSwitches to another user, also known as super-usercutWrites out selected charactersawkProgramming language to parse characterssedProgramming language for character substitutionviStarts the vi editoremacsStarts the emacs editor

Symbol Commands

The symbols shown in Table 1-4 are actually commands, and are used extensively in this book.

Table 1-4 Symbol Commands

CommandDescription( )Runs the enclosed command in a sub-shell(( ))Evaluates and assigns value to a variable and does math in a shell$(( ))Evaluates the enclosed expression[ ]Same as the test command< >Used for string comparison$( )Command substitution‘command’Command substitution

Variables

A variable is a character string to which we assign a value. The value assigned could be a number, text, filename, device, or any other type of data. A variable is nothing more than a pointer to the actual data. We are going to use variables so much in our scripts that it will be unusual for us not to use them. In this book we are always going to specify a variable in uppercase—for example, UPPERCASE. Using uppercase variable names is not recommended in the real world of shell programming, though, because these uppercase variables may step on system environment variables, which are also in uppercase. Uppercase variables are used in this book to emphasize the variables and to make them stand out in the code. When you write your own shell scripts or modify the scripts in this book, make the variables lowercase text. To assign a variable to point to data, we use UPPERCASE=“value_to_assign” as the assignment syntax. To access the data that the variable, UPPERCASE, is pointing to, we must add a dollar sign, $, as a prefix—for example, $UPPERCASE. To view the data assigned to the variable, we use echo$UPPERCASE, print$UPPERCASE for variables, or cat$UPPERCASE, if the variable is pointing to a file, as a command structure.

Command-Line Arguments

The command-line arguments $1, $2, $3,…$9 are positional parameters, with $0 pointing to the actual command, program, shell script, or function and $1, $2, $3, …$9 as the arguments to the command.

The positional parameters, $0, $2, and so on in a function are for the function's use and may not be in the environment of the shell script that is calling the function. Where a variable is known in a function or shell script is called the scope of the variable.

shift Command

The shift command is used to move positional parameters to the left; for example, shift causes $2 to become $1. We can also add a number to the shift command to move the positions more than one position; for example, shift 3 causes $4 to move to the $1 position.

Sometimes we encounter situations where we have an unknown or varying number of arguments passed to a shell script or function, $1, $2, $3… (also known as positional parameters). Using the shift command is a good way of processing each positional parameter in the order they are listed.

To further explain the shift command, we will show how to process an unknown number of arguments passed to the shell script shown in Listing 1-2. Try to follow through this example shell script structure. This script is using the shift command to process an unknown number of command-line arguments, or positional parameters. In this script we will refer to these as tokens.

Listing 1-2: Example of using the shift command

#!/usr/bin/sh

#

# SCRIPT: shifting.sh

#

# AUTHOR: Randy Michael

#

# DATE:   12/30/2007

#

# REV:    1.1.A

#

# PLATFORM: Not platform dependent

#

# PURPOSE: This script is used to process all of the tokens which

# are pointed to by the command-line arguments, $1, $2, $3,etc…

#

# REV. LIST:

#

# Initialize all variables

TOTAL=0    # Initialize the TOTAL counter to zero

#  Start a while loop

while true

do

     TOTAL=‘expr $TOTAL + 1‘  # A little math in the

                              # shell script, a running

                              # total of tokens processed.

TOKEN=$1    # We always point to the $1 argument with a shift

process each $TOKEN

shift          # Grab the next token, i.e. $2 becomes $1

done

echo “Total number of tokens processed: $TOTAL”

We will go through similar examples of the shift command in great detail later in the book.

Special Parameters $* and $@

There are special parameters that allow accessing all the command-line arguments at once. $* and $@ both will act the same unless they are enclosed in double quotes, “ ”.

Special Parameter Definitions

The $* special parameter specifies all command-line arguments.The $@ special parameter also specifies all command-line arguments.The “$*” special parameter takes the entire list as one argument with spaces between.The “$@” special parameter takes the entire list and separates it into separate arguments.

We can rewrite the shell script shown in Listing 1-2 to process an unknown number of command-line arguments with either the $* or $@ special parameters, as shown in Listing 1-3.

Listing 1-3: Example using the special parameter $*

#!/usr/bin/sh

#

# SCRIPT: shifting.sh

# AUTHOR: Randy Michael

# DATE:   12-31-2007

# REV:    1.1.A

# PLATFORM: Not platform dependent

#

# PURPOSE: This script is used to process all of the tokens which

# Are pointed to by the command-line arguments, $1, $2, $3, etc… -

#

# REV LIST:

#

#

#  Start a for loop

for TOKEN in $*

do

process each $TOKEN

done

We could have also used the $@ special parameter just as easily. As we see in the preceding code segment, the use of the $@ or $* is an alternative solution to the same problem, and it was less code to write. Either technique accomplishes the same task.

Double Quotes, Forward Tics, and Back Tics

How do we know which one of these to use in our scripts, functions, and command statements? This decision causes the most confusion in writing scripts. We are going to set this straight now.

Depending on what the task is and the output desired, it is very important to use the correct enclosure. Failure to use these correctly will give unpredictable results.

We use “, double quotes, in a statement where we want to allow character or command substitution. Double quotes are required when defining a variable with data that contains white space, as shown here.

NAME=“Randal K. Michael”

If the double quotes are missing we get the following error.

NAME=Randal K. Michael

-bash: K.: command not found

We use ’, forward tics (single quotes), in a statement where we do not want character or command substitution. Enclosing in ’, forward tics, is intended to use the literal text in the variable or command statement, without any substitution. All special meanings and functions are removed. It is also used when you want a variable reread each time it is used; for example, ‘$PWD’ is used a lot in processing the PS1 command-line prompt. Additionally, preceding the same string with a backslash, \, also removes the special meaning of a character, or string.

We use ‘, back tics, in a statement where we want to execute a command, or script, and have its output substituted instead; this is command substitution. The ‘ key is located to the left of the 1 key, and below the Escape key, Esc, on most keyboards. Command substitution is also accomplished by using the $(command) command syntax. We are going to see many different examples of these throughout this book.

Using awk on Solaris

We use awk a lot in this book to parse through lines of text. There is one special case where, on Solaris, we must to use nawk instead. If we need to specify a field separator other than a blank space, which is the default field delimiter, using awk -F :, for example, the awk statement will fail on a Solaris machine. To get around this problem, use nawk if we find the UNIX flavor is Solaris. Add the following code segment to the variable declaration section of all your shell scripts to eliminate the problem:

# Setup the correct awk usage. Solaris needs to

# use nawk instead of awk.

case $(uname) in

SunOS) alias awk=nawk

       ;;

esac

Using the echo Command Correctly

We use the echo command to display text. The echo command allows a lot of cursor control using backslash operators: \n for a new line, \c to continue on the same line, \b to backspace the cursor, \t for a tab, \r for a carriage return, and \v to move vertically one line. In Korn shell the echo command recognizes these command options by default. In Bash shell we must add the -e switch to the echo command, echo -e “\n” for one new line.

We can query the system for the executing shell by querying the $SHELL shell variable in the script. Many Linux distributions will execute in a Bash shell even though we specify Korn shell on the very first line of the script. Because Bash shell requires the use of the echo -e switch to enable the backslash operators, we can use a case statement to alias the echo command to echo -e if the executing shell is */bin/bash. Now when we need to use the echo command, we are assured it will display text correctly.

Add the following code segment to all your Korn shell scripts in the variable declaration section, and this little problem is resolved:

# Set up the correct echo command usage. Many Linux

# distributions will execute in Bash even if the

# script specifies Korn shell. Bash shell requires

# we use echo -e when we use \n, \c, etc.

case $SHELL in

*/bin/bash) alias echo=“echo -e”

            ;;

esac

Math in a Shell Script

We can do arithmetic in a shell script easily. The shell let command and the ((expr)) command expressions are the most commonly used methods to evaluate an integer expression. Later we will also cover the bc function to do floating-point arithmetic.

Operators

The shells use arithmetic operators from the C programming language (see Table 1-5), in decreasing order of precedence.

Table 1-5 Math Operators

OperatorDescription++ --< /editor query >Auto-increment and auto-decrement, both prefix and postfix+Unary plus-Unary minus! ∼Logical negation; binary inversion (one's complement)* / %Multiplication; division; modulus (remainder)+ −Addition; subtraction<< >>Bitwise left shift; bitwise right shift<= >=Less than or equal to; greater than or equal to< >Less than; greater than&Bitwise AND∧Bitwise exclusive OR|Bitwise OR&&Logical AND||Logical OR

A lot of these math operators are used in the book, but not all. In this book we try to keep things very straightforward and not confuse you with obscure expressions.

Built-In Mathematical Functions

The shells provide access to the standard set of mathematical functions. They are called using C function call syntax. Table 1-6 shows a list of shell functions.

Table 1-6 Built-In Shell Functions

NameFunctionabsAbsolute valuelogNatural logarithmacosArc cosinesinSineasinArc sinesinhHyperbolic sinecosCosinesqrtSquare rootcoshHyperbolic cosinetanTangentexpExponential functiontanhHyperbolic tangentintInteger part of floating-point number

We do not have any shell scripts in this book that use any of these built-in shell functions except for the int function to extract the integer portion of a floating-point number.

File Permissions, suid and sgid Programs

After writing a shell script we must remember to set the file permissions to make it executable. We use the chmod command to change the file's mode of operation. In addition to making the script executable, it is also possible to change the mode of the file to always execute as a particular user (suid) or to always execute as a member of a particular system group (sgid). This is called setting the sticky bit. If you try to suid or sgid a shell script, it is ignored for security reasons.

Setting a program to always execute as a particular user, or member of a certain group, is often used to allow all users, or a set of users, to run a program in the proper environment. As an example, most system-check programs need to run as an administrative user, sometimes root. We do not want to pass out passwords, so we can just make the program always execute as root and it makes everyone's life easier. We can use the options shown in Table 1-7 in setting file permissions. Also, please review the chmod man page, man chmod.

Table 1-7 chmod Permission Options

4000Sets user ID on execution2000Sets group ID on execution1000Sets the link permission to directories or sets the save-text attribute for files0400Permits read by owner0200Permits write by owner0100Permits execute or search by owner0040Permits read by group0020Permits write by group0010Permits execute or search by group0004Permits read by others0002Permits write by others0001Permits execute or search by others

By using combinations from the chmod command options, you can set the permissions on a file or directory to anything that you want. Remember that setting a shell script to suid or sgid is ignored by the system.

chmod Command Syntax for Each Purpose

The chmod command can be used with the octal file permission representation or by r, w, x notation. Both of these examples produce the same result.

To Make a Script Executable

chmod 754 my_script.sh

or

chmod u+rwx,g+rx,o+r my_script.ksh

The owner can read, write, and execute. The group can read and execute. The world can read.

To Set a Program to Always Execute as the Owner

chmod 4755 my_program

The program will always execute as the owner of the file if it is not a shell script. The owner can read, write, and execute. The group can read and execute. The world can read and execute. So, no matter who executes this file, it will always execute as if the owner actually executed the program.

To Set a Program to Always Execute as a Member of the File Owner's Group

chmod 2755 my_program

The program will always execute as a member of the file's group, as long as the file is not a shell script. The owner of the file can read, write, and execute. The group can read and execute. The world can read and execute. So, no matter who executes this program, it will always execute as a member of the file's group.

To Set a Program to Always Execute as Both the File Owner and the File Owner's Group

chmod 6755 my_program

The program will always execute as the file's owner and as a member of the file owner's group, as long as the program is not a shell script. The owner of the file can read, write, and execute. The group can read and execute. The world can read and execute. No matter who executes this program, it will always execute as the file owner and as a member of the file owner's group.

Running Commands on a Remote Host

We sometimes want to execute a command on a remote host and have the result displayed locally. An example would be getting filesystem statistics from a group of machines. We can do this with the rsh command. The syntax is rshhostname command_to_execute. This is a handy little tool but two system files will need to be set up on all of the hosts before the rsh command will work. The files are .rhosts, which would be created in the user's home directory and have the file permissions of 600 (permission to read and write by the owner only), and the /etc/hosts.equiv file.

For security reasons the .rhosts and hosts.equiv files, by default, are not set up to allow the execution of a remote shell. Be careful! The systems' security could be threatened. Refer to each operating system's documentation for details on setting up these files.

Speaking of security, a better solution is to use Open Secure Shell (OpenSSH) instead of rsh. OpenSSH is a freeware encrypted replacement for rsh, telnet, and ftp, for the most part. To execute a command on another machine using OpenSSH, use the following syntax:

ssh user@hostname command_to_execute

or

ssh -l user hostname command_to_execute

This command prompts you for a password if the encryption key pairs have not been set up. Setting up the key pair relationships manually usually takes a few minutes, or you can use one of the keyit scripts shown in Listings 1-4 and 1-5 to set up the keys for you. The details of the procedure are shown in the ssh manual page (man ssh). You can download the OpenSSH code from http://www.openssh.org.

The keyit.dsa script in Listing 1-4 will set up DSA keys, if the DSA keys exist.

Listing 1-4: keyit.dsa script used to set up DSA SSH keys

#!/bin/bash

#

# SCRIPT: keyit.dsa

# PURPOSE: This script is used to set up DSA SSH keys. This script must

#     be executed by the user who needs the keys setup.

REM_HOST=$1

cat $HOME/.ssh/id_dsa.pub | ssh $REM_HOST “cat >> ∼/.ssh/authorized_keys”

The keyit.rsa script in Listing 1-5 will set up the RSA keys, if the RSA keys exist.

Listing 1-5: keyit.rsa script used to set up RSA SSH keys

#!/bin/bash

#

# SCRIPT: keyit.rsa

# PURPOSE: This script is used to set up RSA SSH keys.

This script must be executed by the user who needs the keys setup.

REM_HOST=$1

cat $HOME/.ssh/id_rsa.pub | ssh $REM_HOST “cat >> ∼/.ssh/authorized_keys”

If you need to set up the encryption keys for a new user, first su to that user ID, and then issue one of the following commands.

To set up DSA keys issue this command:

ssh-keygen -t dsa

To set up RSA keys issue this one:

ssh-keygen -t rsa

Read the ssh-keygen man page for more details: man ssh-keygen.

Setting Traps

When a program is terminated before it would normally end, we can catch an exit signal. This is called a trap. Table 1-8 lists some of the exit signals.

Table 1-8 Exit Signals

0—Normal termination, end of script1SIGHUPHang up, line disconnected2SIGINTTerminal interrupt, usually Ctrl + C3SIGQUITQuit key, child processes to die before terminating9SIGKILLkill -9 command, cannot trap this type of exit status15SIGTERMkill command's default action19SIGSTOPStop, usually Ctrl + z

To see the entire list of supported signals for your operating system, enter the following command:

# kill -l     [That's kill -(ell)]

This is a really nice tool to use in our shell scripts. On catching a trapped signal we can execute some cleanup commands before we actually exit the shell script. Commands can be executed when a signal is trapped. If the following command statement is added in a shell script, it will print to the screen “EXITING on a TRAPPED SIGNAL” and then make a clean exit on the signals 1, 2, 3, and 15. We cannot trap a kill-9.

trap ‘echo “\nEXITING on a TRAPPED SIGNAL”;exit’ 1 2 3 15

We can add all sorts of commands that may be needed to clean up before exiting. As an example, we may need to delete a set of files that the shell script created before we exit.

User-Information Commands

Sometimes we need to query the system for some information about users on the system.

who Command

The who command gives this output for each logged-in user: username, tty, login time, and where the user logged in from:

rmichael     pts/0          Mar 13 10:24          192.168.1.104

root         pts/1          Mar 15 10:43          (yogi)

w Command

The w command is really an extended who. The output looks like the following:

12:29PM    up 27 days,   21:53,2 users, load average  1.03,  1.17, 1.09

User       tty      login@         idle     JCPU  PCPU    what

rmichael   pts/0    Mon10AM 0      3:00     1             w

root       pts/1    10:42AM 37     5:12     5:12          tar

Notice that the top line of the preceding output is the same as the output of the uptime command. The w command gives a more detailed output than the who command by listing job process time and total user process time, but it does not reveal where the users have logged in from. We often are interested in this for security purposes. One nice thing about the w command's output is that it also lists what