Other Books by the Author
Command Line Kung Fu: Bash Scripting Tricks, Linux Shell Programming Tips, and Bash One-liners
http://www.linuxtrainingacademy.com/command-line-kung-fu-book
High Availability for the LAMP Stack: Eliminate Single Points of Failure and Increase Uptime for Your Linux, Apache, MySQL, and PHP Based Web Applications
http://www.linuxtrainingacademy.com/ha-lamp-book
Linux for Beginners: An Introduction to the Linux Operating System and Command Line
http://www.linuxtrainingacademy.com/linux
Python Programming for Beginners
http://www.linuxtrainingacademy.com/python-programming-for-beginners
Introduction
I'm lazy. I admit it. I believe so strongly in being lazy that I'll do almost anything to facilitate even more laziness in the future.
For example, if I think there is a slight chance that I will ever have to perform the same set of commands again, I create a shell script then and there. When I need to do that task again, I lazily execute my script. If maintenance needs to be performed on a system at 2:00 in the morning, I write a script that does the required work and schedule a job to run it. Lazy people love to sleep.
I also believe in helping people find their inner laziness. Why? Because lazy people solve problems. They eliminate the unnecessary. They simplify the complex.
That's the reason I've written this book.
I want to share with you some of my favorite tips and tricks I've used to automate repetitive, monotonous, tedious, and complex tasks. May they inspire you to be lazy.
Before we get started I recommend that you download the shell scripts used in this book by visiting: http://www.linuxtrainingacademy.com/shell-scripts
Shell Scripting, Succinctly
A script is a command line program that contains a series of commands. The commands contained in the script are executed by an interpreter. In the case of shell scripts, the shell acts as the interpreter and executes the commands listed in the script one after the other.
Anything you can execute at the command line, you can put into a shell script. Shell scripts are great at automating tasks. If you find yourself running a series of commands to accomplish a given task and will need to perform that task again in the future, you canand probably shouldcreate a shell script for that task.
Let's look at a simple shell script. The name of this script is script1.sh .
#!/bin/bash
echo "Scripting is fun!"
Before you try to execute the script, make sure that it is executable.
$ chmod 755 script1.sh
Here is what happens when you execute the script.
$ ./script1.sh
Scripting is fun!
$
The Shebang
You'll notice that the first line of the script starts with #! followed by the path to the bash shell program, /bin/bash . The number sign is very similar to the sharp sign used in music notation. Also, some people refer to the exclamation mark as a "bang." So, #! can be spoken as "sharp bang." The term "Shebang" is an inexact contraction of "sharp bang."
When a script's first line starts with a shebang, what follows is used as the interpreter for the commands listed in the script. Here are three examples of shell scripts, each using a different shell program as the interpreter.
#!/bin/csh
echo "This script uses csh as the interpreter."
#!/bin/ksh
echo "This script uses ksh as the interpreter."
#!/bin/zsh
echo "This script uses zsh as the interpreter."
When you execute a script that contains a shebang, what actually happens is that the interpreter is executed and the path used to call the script is passed as an argument to the interpreter. You can prove this by examining the process table.
Let's start this script, sleepy.sh , in the background and look at the process table.
The contents of sleepy.sh :
#!/bin/bash
sleep 90
Let's execute it in the background and take a look at the processes.
$ ./sleepy.sh &
[1] 16796
$ ps -fp 16796
UID PID PPID C STIME TTY TIME CMD
jason 16796 16725 0 22:50 pts/0 00:00:00 /bin/bash ./sleepy.sh
$
You can see that what is actually running is /bin/bash ./sleepy.sh . Let's use a full path to the script.
$ /tmp/sleepy.sh &
[1] 16804
$ ps -fp 16804
UID PID PPID C STIME TTY TIME CMD
jason 16804 16725 0 22:51 pts/0 00:00:00 /bin/bash /tmp/sleepy.sh
$
Sure enough, /bin/bash /tmp/sleepy.sh is being executed. Also, you can see that /bin/bash is executing the sleep command, which is the first and only command command in the shell script.
$ ps -ef| grep 16804 | grep -v grep
jason 16804 16725 0 22:51 pts/0 00:00:00 /bin/bash /tmp/sleepy.sh
jason 16805 16804 0 22:51 pts/0 00:00:00 sleep 90
$ pstree p 16804
sleepy.sh(16804)sleep(16805)
$
If you do not supply a shebang and specify an interpreter on the first line of the script, the commands in the script will be executed using your current shell. Even though this can work just fine under many circumstances, it's best to be explicit and specify the exact interpreter to be used with the script. For example, there are features and syntax that work just fine with the bash shell that will not work with the csh shell.
Also, you don't have to use a shell as the interpreter for your scripts. Here is an example of a Python script named hi.py .
#!/usr/bin/python
print "This is a Python script."
Let's make it executable and run it.
$ chmod 755 hi.py
$ ./hi.py
This is a Python script.
$
For more information on python programming and scripting, see my book Python Programming for Beginners at http://www.linuxtrainingacademy.com/python-book.
Let's get back to shell scripting.
Variables
You can use variables in your shell scripts. Variables are simply storage locations that have a name. You can think of variables as name-value pairs. To assign a value to a variable, use the syntax VARIABLE_NAME="Value" . Do not use spaces before or after the equals sign. Also, variables are case sensitive, and, by convention, variable names are in uppercase.
#!/bin/bash
MY_SHELL="bash"
To use a variable, precede the variable name with a dollar sign.
#!/bin/bash
MY_SHELL="bash"
echo "I like the $MY_SHELL shell."
You can also enclose the variable name in curly braces and precede the opening brace with a dollar sign. Syntax: ${VARIABLE_NAME} .
#!/bin/bash
MY_SHELL="bash"
echo "I like the ${MY_SHELL} shell."
Here is the output of the script:
I like the bash shell.
The curly brace syntax is optional unless you need to immediately precede or follow the variable with additional data.
#!/bin/bash
MY_SHELL="bash"
echo "I am ${MY_SHELL}ing on my keyboard."
Output:
I am bashing on my keyboard.
If you do not encapsulate the variable name in curly braces the shell will treat the additional text as part of the variable name. Since a variable with that name does not exist, nothing is put in its place.