Programming Tools & Computer Science I

CSC 185 & 201, Spring 2013, Northern Virginia Community College

Week 15: Bash scripting

2013-05-01

We'll look at more advanced usage of the Bash shell.

Shell initialization and aliases

When you start an interactive Bash shell, it reads several files to customize your environment. The one we'll customize is ~/.bash_profile (~ indicates your home directory). This file contains commands that are run when you first log in (the ~/.bashrc file is run when you start a new shell after that, like if you type the bash command). You can edit the file using the nano command.

If you find that you frequently use the same special command, you can assign it a shorter name (an alias) using the alias command. This just tells the shell to replace the short command name with the full version every time it appears. Some examples:

You'll usually define aliases in your .bashrc.

Variables

Variables work much like on the Windows command line, with a few small differences. Here's a sample shell session:


$ GREETING="Hello there."
$ echo $GREETING
Hello there.
$ printenv GREETING
$ export GREETING
$ printenv GREETING
Hello there.
$ LONG_GREETING="Hello hello... $GREETING"
$ echo ${LONG_GREETING}
Hello hello... Hello there.
$ SINGLE_QUOTES='Hello hello... $GREETING'
$ echo $SINGLE_QUOTES
Hello hello... $GREETING

A few things to notice:

Unix-based operating systems use a PATH variable just like Windows. The only difference is that it's usually a colon-separated of directories, rather than semicolon-separated:


$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/share/java/
apache-ant/bin:/opt/java/bin:/opt/java/db/bin:/opt/java/jre/bin:/usr/bin/core
_perl:/home/jlepak/bin:/opt/java/bin:/home/jlepak/bin:/opt/java/bin

Command substitution

You can treat the output of a command much like a variable, with similar syntax:


$ pwd
/home/jlepak
$ DIR="My working directory is: $(pwd)"
$ echo $DIR
My working directory is: /home/jlepak

In the above example, $(pwd) was replaced with the output from the pwd command.

Functions and scripts

You can create scripts by inserting a bunch of commands (just like ones you would type) into a file. There is special syntax for defining functions, which work mostly work just like scripts.

Basic setup

Here's a very basic script:


#!/usr/bin/env bash

echo 'Hello there!'

The top line is used by the shell to determine what program actually runs the script. We'll only be talking about Bash scripts, so you'll always have that same line at the top. # usually indicates a comment, but if the first line of a script starts with #! it is used to identify the program that runs the script.

Copy that text into a file called hello.sh, and then try to run it (note that you have to include the directory name, using . to indicate the current directory, unless . is in your PATH):

$ ./hello.sh
-bash: permission denied: ./hello.sh

The reason for such an error (if you get an error) is that you need to set the file permissions properly in order to run it as a program:

$ chmod u+x hello.sh
$ ./hello.sh
Hello there!

chmod changes the file mode (file permissions), and u+x indicates that the user (owner of the file) should be able to execute it.

Alternately, you can just explicitly tell Bash to run your program:

$ bash hello.sh
Hello there!

In that case, you don't need the top line of the script either.

Providing input for scripts and functions

The main way of providing input to scripts or functions is through the command line arguments. These are available in special variables: $1, $2, etc. hold the command line arguments.

The special variable $@ refers to all of the command line arguments, which you can pass on to other commands.

To create interactive scripts, you can use the read command, which reads a line of input and stores it in a named variable:

$ read NAME
Joel (typed by user)
$ echo $NAME
Joel

Functions

If you have a commonly used operation that's a little too complex to use a simple alias, you can define a function in your .bashrc. Other than the notation, functions work just like scripts:

$ hello () {
    echo "Hello ${1}."
}
$ hello Joel
Hello Joel.

Readings

Read chapters 3, 4, 7, and 8 in the Software Carpentry tutorial.

Here are a couple of tutorials you can reference: