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:
alias ls='ls --color=tty'
will give colorized output in a terminal.
alias rm='rm -i'
will cause rm
to always prompt before deleting.
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:
- You have to quote values on the right hand side of an assignment if they
contain spaces. In general, quoting rules are very complicated,
but the common cases are pretty easy.
- You can't leave space around the
=
(like the Windows shell).
- You use a variable by prefixing it with
$
, rather than surrounding with %
like in the Windows shell.
- Programs you start from the command line (like
printenv
, which is used
to print the values of environment variables) can't see the values you
set unless you export the variables.
- Variables can expand inside double quotes, but not single quotes.
Single quotes are used when you want to avoid expanding variables or
other special characters.
$VAR
and ${VAR}
usually work the same, but the second form has more
options, and can be used when you want to do something like
VAR2="xx${VAR}xx"
.
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: