Writing shell scripts Flashcards

1
Q

What are shell scripts?

A

In the simplest terms, a shell script is a file containing a series of commands. The shell reads this file and carries out the commands as though they have been entered directly on the command line.

The shell is somewhat unique, in that it is both a powerful command line interface to the system and a scripting language interpreter. As we will see, most of the things that can be done on the command line can be done in scripts, and most of the things that can be done in scripts can be done on the command line.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

To successfully write a shell script, you have to do three things:

A
  1. Write a script
  2. Give the shell permission to execute it
  3. Put it somewhere the shell can find it
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Writing a script

A

A shell script is a file that contains ASCII text. To create a shell script, you use a text editor. A text editor is a program, like a word processor, that reads and writes ASCII text files. There are many, many text editors available for your Linux system, both for the command line environment and the GUI environment.

Name/Description/Interface

vi, vim
The granddaddy of Unix text editors, vi, is infamous for its difficult, non-intuitive command structure. On the bright side, vi is powerful, lightweight, and fast. Learning vi is a Unix rite of passage, since it is universally available on Unix-like systems. On most Linux distributions, an enhanced version of the traditional vi editor called vim is used.
command line

Emacs
The true giant in the world of text editors is Emacs by Richard Stallman. Emacs contains (or can be made to contain) every feature ever conceived for a text editor. It should be noted that vi and Emacs fans fight bitter religious wars over which is better.
command line

nano
nano is a free clone of the text editor supplied with the pine email program. nano is very easy to use but is very short on features. I recommend nano for first-time users who need a command line editor.
command line

gedit
gedit is the editor supplied with the Gnome desktop environment.
graphical

kwrite
kwrite is the “advanced editor” supplied with KDE. It has syntax highlighting, a helpful feature for programmers and script writers.
graphical

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

chmod 755

A

give you read, write, and execute permission. Everybody else will get only read and execute permission. If you want your script to be private (i.e., only you can read and execute), use “700” instead.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

!/bin/bash

A

The first line of the script is important. This is a special clue, called a shebang, given to the shell indicating what program is used to interpret the script. In this case, it is /bin/bash. Other scripting languages such as Perl, awk, tcl, Tk, and python also use this mechanism.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Paths

A

When you type in the name of a command, the system does not search the entire computer to find where the program is located. That would take a long time. You have noticed that you don’t usually have to specify a complete path name to the program you want to run, the shell just seems to know.

Well, you are right. The shell does know. Here’s how: the shell maintains a list of directories where executable files (programs) are kept, and only searches the directories in that list. If it does not find the program after searching each directory in the list, it will issue the famous command not found error message.

This list of directories is called your path.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

How to view the list of directories (your path)?

A

echo $PATH

This will return a colon separated list of directories that will be searched if a specific path name is not given when a command is attempted.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Add directories to your path

A

export PATH=$PATH:directory

(where directory is the name of the directory you want to add)

A better way would be to edit your .bash_profile or .profile file (depending on your distribution) to include the above command. That way, it would be done automatically every time you log in.

Most Linux distributions encourage a practice in which each user has a specific directory for the programs he/she personally uses. This directory is called bin and is a subdirectory of your home directory.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Environment

A

During your session, the system is holding a number of facts about the world in its memory. This information is called the environment. The environment contains such things as your path, your user name, the name of the file where your mail is delivered, and much more. You can see a complete list of what is in your environment with the set command.

Two types of commands are often contained in the environment. They are aliases and shell functions.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

How is the environment established?

A

When you log on to the system, the bash program starts, and reads a series of configuration scripts called startup files. These define the default environment shared by all users. This is followed by more startup files in your home directory that define your personal environment. The exact sequence depends on the type of shell session being started. There are two kinds: a login shell session and a non-login shell session. A login shell session is one in which we are prompted for our user name and password; when we start a virtual console session, for example. A non-login shell session typically occurs when we launch a terminal session in the GUI.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Aliases

A

An alias is an easy way to create a new command which acts as an abbreviation for a longer one. It has the following syntax:

alias name=value
where name is the name of the new command and value is the text to be executed whenever name is entered on the command line.

Let’s create an alias called “l” and make it an abbreviation for the command “ls -l”. Make sure you are in your home directory. Using your favorite text editor, open the file .bashrc and add this line to the end of the file:

alias l=’ls -l’

It’s just another shell builtin

You can create your aliases directly at the command prompt; however they will only remain in effect during your current shell session.

Another example:
alias today=’date +”%A, %B %-d, %Y”’

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Shell functions

A

Aliases are good for very simple commands, but if you want to create something more complex, you should try shell functions . Shell functions can be thought of as “scripts within scripts” or little sub-scripts.

Example:
today() {
    echo -n "Today's date is: "
    date +"%A, %B %-d, %Y"
}

Believe it or not, () is a shell builtin too, and as with alias, you can enter shell functions directly at the command prompt.
However, again like alias, shell functions defined directly on the command line only last as long as the current shell session.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Here script

A

!/bin/bash

A here script (also sometimes called a here document) is an additional form of I/O redirection. It provides a way to include content that will be given to the standard input of a command. In the case of the script below, the standard input of the cat command was given a stream of text from our script.

Since many types of markup used in html incorporate quotation marks themselves, it makes using a quoted string a little awkward. A quoted string can be used but each embedded quotation mark will need to be escaped with a backslash character.

sysinfo_page - A script to produce an HTML file

cat &laquo_space;EOF

The title of your page

Your page content goes here.

EOF

A here script is constructed like this:

command &laquo_space;token
content to be used as command’s standard input
token

The token can be any string of characters. I use “EOF” (EOF is short for “End Of File”) because it is traditional, but you can use anything, as long as it does not conflict with a bash reserved word. The token that ends the here script must exactly match the one that starts it, or else the remainder of your script will be interpreted as more standard input to the command.

One more trick:
Changing the the “<

    My System Information

<h1>My System Information</h1>
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Variables

A

Variables are areas of memory that can be used to store information and are referred to by a name. In the case of our script, we created a variable called “title” and placed the phrase “My System Information” into memory. Inside the here script that contains our HTML, we use “$title” to tell the shell to perform parameter expansion and replace the name of the variable with the variable’s contents.

Here's the improved script:
#!/bin/bash

sysinfo_page - A script to produce an HTML file

title=”My System Information”

cat <

    $title

<h1>$title</h1>
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

How to create a variable

A

To create a variable, put a line in your script that contains the name of the variable followed immediately by an equal sign (“=”). No spaces are allowed. After the equal sign, assign the information you wish to store.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Rules for variable names

A
  1. Names must start with a letter.
  2. A name must not contain embedded spaces. Use underscores instead.
  3. You cannot use punctuation marks.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

Environment Variables

A

!/bin/bash

When you start your shell session, some variables are already set by the startup file we looked at earlier. To see all the variables that are in your environment, use the printenv command. One variable in your environment contains the host name for your system. We will add this variable to our script like so:

sysinfo_page - A script to produce an HTML file

title=”System Information for”

cat <

    $title $HOSTNAME

<h1>$title $HOSTNAME</h1>
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

Executing a command in a script

A

$(some_command)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

Assigning results of a command to a variable

A

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”

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Constants

A

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 given an uppercase name to remind the programmer that it should be considered a constant even if it’s not being enforced.

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.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

Shell functions

A

show_uptime()
{

}

Important points:
First, they must appear before you attempt to use them. Second, the function body (the portions of the function between the { and } characters) must contain at least one valid command. As written, the script will not execute without error, because the function bodies are empty. The simple way to fix this is to place a return statement in each function body. After you do this, our script will execute successfully again.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

Stubbing

A

When you are developing a program, it is is often a good practice to add a small amount of code, run the script, add some more code, run the script, and so on. This way, if you introduce a mistake into your code, it will be easier to find and correct.

As you add functions to your script, you can also use a technique called stubbing to help watch the logic of your script develop. Stubbing works like this: imagine that we are going to create a function called “system_info” but we haven’t figured out all of the details of its code yet. Rather than hold up the development of the script until we are finished with system_info, we just add an echo command like this:

system_info()
{
    # Temporary function stub
    echo "function system_info"
}

The reason we use an echo command is so we get some feedback from the script to indicate that the functions are being executed.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

command that outputs several interesting facts about the system, including the length of time the system has been “up” (running) since its last re-boot, the number of users and recent system load

A

uptime

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

command to provide a summary of the space used by all of the mounted file systems

A

df

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

examine the contents of the /home directory

A

du -s (must be run as SuperUser)

26
Q

<pre></pre>

tags in HTML

A

The HTML <pre> element represents pre-formatted text which is to be presented exactly as written in the HTML file. The text is typically rendered using a non-proportional (“monospace”) font. Whitespace inside this element is displayed as written.</pre>

27
Q

Exit status

A

Commands (including the scripts and shell functions we write) issue a value to the system when they terminate, called an exit status. This value, which is an integer in the range of 0 to 255, indicates the success or failure of the command’s execution. By convention, a value of zero indicates success and any other value indicates failure.

Man pages often include a section entitled “Exit Status,” describing what codes are used. However, a zero always indicates success.

28
Q

true and false

A

The shell provides two extremely simple builtin commands that do nothing except terminate with either a zero or one exit status. The true command always executes successfully and the false command always executes unsuccessfully

29
Q

How to display the exit status of the last executed command

A

echo $?

From the manual: (acessible by calling man bash in your shell):
$? Expands to the exit status of the most recently executed foreground pipeline.

30
Q

if/else statement

A

if [ -f .bash_profile ]; then
echo “You have a .bash_profile. Things are fine.”
else
echo “Yikes! You have no .bash_profile!”
fi

31
Q

The test command

A

The test command is used most often with the if command to perform true/false decisions. The command is unusual in that it has two different syntactic forms:

# First form:
test expression
# Second form:
[ expression ]

The test command works simply. If the given expression is true, test exits with a status of zero; otherwise it exits with a status of 1.

The neat feature of test is the variety of expressions you can create.

Since test is a shell builtin, use “help test” to see a complete list of conditions that test can evaluate.

Notice that the spaces required between the “[” and the beginning of the expression are required. Likewise, the space between the end of the expression and the trailing “]”.

32
Q

List of conditions test can evaluate

A

Expression/Description

-d file
True if file is a directory.

-e file
True if file exists.

-f file
True if file exists and is a regular file.

-L file
True if file is a symbolic link.

-r file
True if file is a file readable by you.

-w file
True if file is a file writable by you.

-x file
True if file is a file executable by you.

file1 -nt file2
True if file1 is newer than (according to modification time) file2

file1 -ot file2
True if file1 is older than file2

-z string
True if string is empty.

-n string
True if string is not empty.

string1 = string2
True if string1 equals string2.

string1 != string2
True if string1 does not equal string2.

33
Q

clear the screen and execute the list command

A

clear; ls

34
Q

Indenting

A

for the benefit of readability, it is traditional to indent all blocks of conditional code; that is, any code that will only be executed if certain conditions are met. The shell does not require this; it is done to make the code easier to read.

Alternate form

if [ -f .bash_profile ]
then
echo “You have a .bash_profile. Things are fine.”
else
echo “Yikes! You have no .bash_profile!”
fi

Another alternate form

if [ -f .bash_profile ]
then echo “You have a .bash_profile. Things are fine.”
else echo “Yikes! You have no .bash_profile!”
fi

35
Q

exit

A

In order to be good script writers, we must set the exit status when our scripts finish. To do this, use the exit command. The exit command causes the script to terminate immediately and set the exit status to whatever value is given as an argument. For example:

exit 0

exits your script and sets the exit status to 0 (success), whereas

exit 1

exits your script and sets the exit status to 1 (failure).

36
Q

id command

A

can tell us who the current user is. When executed with the “-u” option, it prints the numeric user id of the current user.

[me@linuxbox me]$ id -u
501
[me@linuxbox me]$ su
Password:
[root@linuxbox me]# id -u
0

If the superuser executes id -u, the command will output “0.” This fact can be the basis of if statements in our scripts

37
Q

> &2

A

Another form of I/O redirection

You will often notice this in routines that display error messages. If this redirection were not done, the error message would go to standard output. With this redirection, the message is sent to standard error. Since we are executing our script and redirecting its standard output to a file, we want the error messages separated from the normal output.

Example:
if [ $(id -u) != "0" ]; then
    echo "You must be the superuser to run this script" >&amp;2
    exit 1
fi
38
Q

variable_name=

A

There is nothing wrong with this. variable_name= is perfectly good syntax. You will sometimes want to set a variable’s value to nothing.

39
Q

Tips for debugging your shell scripts

A
  • Comment out blocks of code

- Use echo commands to verify your assumptions

40
Q

Tracing

A

Adding a -x to the first line in your script (like this: #!/bin/bash -x)

Now, when you run your script, bash will display each line (with expansions performed) as it executes it. This technique is called tracing.

Alternately, you can use the set command within your script to turn tracing on and off. Use set -x to turn tracing on and set +x to turn tracing off.

41
Q

Get input from keyboard

A

!/bin/bash

use the read command. The read command takes input from the keyboard and assigns it to a variable. Here is an example:

echo -n “Enter some text > “
read text
echo “You entered: $text”

42
Q

Echo -n

A

“-n” given to the echo command causes it to keep the cursor on the same line; i.e., it does not output a linefeed at the end of the prompt.

43
Q

What happens if you don’t give the read command a variable to assign its output?

A

If you don’t give the read command the name of a variable to assign its input, it will use the environment variable REPLY.

44
Q

read command’s options

A

The two most interesting ones are -t and -s.

The -t option followed by a number of seconds provides an automatic timeout for the read command. This means that the read command will give up after the specified number of seconds if no response has been received from the user. This option could be used in the case of a script that must continue (perhaps resorting to a default response) even if the user does not answer the prompts.

The -s option causes the user’s typing not to be displayed. This is useful when you are asking the user to type in a password or other confidential information.

45
Q

Arithmetic with fractional numbers (non-integers)

A

If you must deal with fractional numbers, there is a separate program called bc which provides an arbitrary precision calculator language. It can be used in shell scripts, but is beyond the scope of this tutorial.

46
Q

Integer arithmetic

A

Whitespace is ignored:

[me@linuxbox me]$ echo $((2+2))
4
[me@linuxbox me]$ echo $(( 2+2 ))
4
[me@linuxbox me]$ echo $(( 2 + 2 ))
4
47
Q

Multi-branch if/else statement

A

!/bin/bash

echo -n "Enter a number between 1 and 3 inclusive > "
read character
if [ "$character" = "1" ]; then
    echo "You entered one."
elif [ "$character" = "2" ]; then
    echo "You entered two."
elif [ "$character" = "3" ]; then
    echo "You entered three."
else
    echo "You did not enter a number between 1 and 3."
fi
48
Q

Case statement (prettier way to do multi-branch if/else)

A

!/bin/bash

It has the following form:
case word in
patterns ) commands ;;
esac

case selectively executes statements if word matches a pattern. You can have any number of patterns and statements. Patterns can be literal text or wildcards. You can have multiple patterns separated by the “|” character.

Note how the closing tag for if’s and cases is to write the word in reverse

echo -n "Enter a number between 1 and 3 inclusive > "
read character
case $character in
    1 ) echo "You entered one."
        ;;
    2 ) echo "You entered two."
        ;;
    3 ) echo "You entered three."
        ;;
    * ) echo "You did not enter a number between 1 and 3."
esac
49
Q

Shell provides 3 commands for looping

A

!/bin/bash

while, until, and for

number=0
until [ "$number" -ge 10 ]; do
    echo "Number = $number"
    number=$((number + 1))
done

for variable in words; do
commands
done

for i in word1 word2 word3; do
echo $i
done

50
Q

Another “until” example

A

!/bin/bash

selection=
until [ "$selection" = "0" ]; do
    echo "
    PROGRAM MENU
    1 - Display free disk space
    2 - Display free memory
    0 - exit program
"
    echo -n "Enter selection: "
    read selection
    echo ""
    case $selection in
        1 ) df ;;
        2 ) free ;;
        0 ) exit ;;
        * ) echo "Please enter 1, 2, or 0"
    esac
done
51
Q

When your computer hangs

A

We have all had the experience of an application hanging. Hanging is when a program suddenly seems to stop and become unresponsive. While you might think that the program has stopped, in most cases, the program is still running but its program logic is stuck in an endless loop.

Imagine this situation: you have an external device attached to your computer, such as a USB disk drive but you forgot to turn it on. You try and use the device but the application hangs instead. When this happens, you could picture the following dialog going on between the application and the interface for the device:

Application: Are you ready?
Interface: Device not ready.

Application: Are you ready?
Interface: Device not ready.

Application: Are you ready?
Interface: Device not ready.

Application: Are you ready?
Interface: Device not ready.

and so on, forever.

52
Q

Well written software’s handling of infinite loops

A

Well-written software tries to avoid this situation by instituting a timeout. This means that the loop is also counting the number of attempts or calculating the amount of time it has waited for something to happen. If the number of tries or the amount of time allowed is exceeded, the loop exits and the program generates an error and exits.

53
Q

Positional paramaters

A

Can refer to $0, $1, $2, $3 for the parameters

54
Q

for loops with positional parameters

A

!/bin/bash

for i in “$@”; do
echo $i
done

The shell variable “$@” contains the list of command line arguments. This technique is often used to process a list of files on the command line. Here is a another example:

for filename in "$@"; do
    result=
    if [ -f "$filename" ]; then
        result="$filename is a regular file"
    else
        if [ -d "$filename" ]; then
            result="$filename is a directory"
        fi
    fi
    if [ -w "$filename" ]; then
        result="$result and it is writable"
    else
        result="$result and it is not writable"
    fi
    echo "$result"
done
55
Q

Produce formatted output

A

command printf, which is used to produce formatted output according to the contents of a format string. printf comes from the C programming language and has been implemented in many other programming languages including C++, Perl, awk, java, PHP, and of course, bash.

56
Q

command used to search for files or directories that meet specific criteria. In the home_space function, we use find to list the directories and regular files in each home directory. Using the wc command, we count the number of files and directories found.

A

find

57
Q

AND

A

&&

The control operators && and || denote AND lists and OR lists, respectively. An AND list has the form

command1 && command2
command2 is executed if, and only if, command1 returns an exit status of zero.

An OR list has the form

command1 || command2

58
Q

OR

A

||

59
Q

trap command

A

The trap command allows you to execute a command when a signal is received by your script. It works like this:

trap arg signals
“signals” is a list of signals to intercept and “arg” is a command to execute when one of the signals is received

60
Q

One signal you can’t trap

A

There is one signal that you cannot trap: SIGKILL or signal 9. The kernel immediately terminates any process sent this signal and no signal handling is performed. Since it will always terminate a program that is stuck, hung, or otherwise screwed up, it is tempting to think that it’s the easy way out when you have to get something to stop and go away. Often you will see references to the following command which sends the SIGKILL signal:

kill -9
However, despite its apparent ease, you must remember that when you send this signal, no processing is done by the application. Often this is OK, but with many programs it’s not. In particular, many complex programs (and some not-so-complex) create lock files to prevent multiple copies of the program from running at the same time. When a program that uses a lock file is sent a SIGKILL, it doesn’t get the chance to remove the lock file when it terminates. The presence of the lock file will prevent the program from restarting until the lock file is manually removed.

Be warned. Use SIGKILL as a last resort.

61
Q

clean_up function

A

While the trap command has solved the problem, we can see that it has some limitations. Most importantly, it will only accept a single string containing the command to be performed when the signal is received. You could get clever and use “;” and put multiple commands in the string to get more complex behavior, but frankly, it’s ugly. A better way would be to create a function that is called when you want to perform any actions at the end of your script. In my scripts, I call this function clean_up.