Comments. Lines beginning with a # (with the exception
of #!) are comments.
# This line is a comment.
Comments may also occur at the end of a command.
echo "A comment will follow." # Comment here.
Comments may also follow white space at the beginning of a line.
# A tab precedes this comment.
Caution
A command may not follow after a comment on the
same line. There is no method of terminating the comment,
in order for "live code" to begin on the same
line. Use a new line for the next command.
;
Command separator. Permits putting two or more commands on the same line.
echo hello; echo there
Note that the ; sometimes needs to be escaped (\).
.
"dot" command. Equivalent to source, explained further on
(see Example 3-44).
:
null command. Exit status 0, alias for
true
Endless loop:
while :
do
operation-1
operation-2
...
operation-n
done
Placeholder in if/then test:
if condition
then : # Do nothing and branch ahead
else
take-some-action
fi
Provides a placeholder where a binary operation is
expected, see Section 3.3.1.
: ${username=`whoami`}
# ${username=`whoami`} without the leading : gives an error
Evaluate string of variables using
"parameter substitution", see Example 3-6:
: ${HOSTNAME?} ${USER?} ${MAIL?}
Prints error message if one or more of essential environmental
variables not set.
()
command group.
(a=hello; echo $a)
Note: A listing of commands within
parentheses starts a
subshell (see Section 3.16).
grep Linux {file?.txt,*.list}
# Finds all instances of the work "Linux"
# in the files "fileA.txt", "file2.txt", "word.list", "vegetable.list", etc.
A command may act upon a comma-separated list of file specs within
braces. Filename expansion (globbing)
applies to the file specs between the braces.
Warning
No spaces allowed within the braces.
{}
Block of code. Also referred to as an "inline group",
this construct, in effect, creates an anonymous
function. Similar to a function, a code block permits
isolation from the remainder of the script, with its
own local variables visible only within the scope of
the block.
The code block enclosed in braces may have I/O redirected to
and from it. See Section 3.13 for a detailed
discussion of I/O redirection.
Example 3-2. Code blocks and I/O redirection
#!/bin/bash
{
read fstab
} < /etc/fstab
echo "First line in /etc/fstab is:"
echo "$fstab"
exit 0
Example 3-3. Saving the results of a code block to a file
#!/bin/bash
# rpm-check
# ---------
# Queries an rpm file for description, listing, and whether it can be installed.
# Saves output to a file.
#
# This script illustrates using a code block.
NOARGS=1
if [ -z $1 ]
then
echo "Usage: `basename $0` rpm-file"
exit $NOARGS
fi
{
echo
echo "Archive Description:"
rpm -qpi $1 #Query description.
echo
echo "Archive Listing:"
rpm -qpl $1 #Query listing.
echo
rpm -i --test $1 #Query whether rpm file can be installed.
if [ ! $? ]
then
echo "$1 can be installed."
else
echo "$1 cannot be installed."
fi
echo
} > $1.test # Redirects output of everything in block to file.
echo "Results of rpm test in file $1.test"
# See rpm man page for explanation of options.
exit 0
/{}
file pathname. Mostly used in 'find' constructs.
>>&>><
redirection.
scriptname >filename redirects the output of
scriptname to file
filename. Overwrite
filename if it already exists.
command >&2 redirects output of
command to stderr.
scriptname >>filename appends
the output of scriptname
to file filename. If
filename does not already exist,
it will be created.
For a more detailed explanation, see Section 3.13.
<<
redirection used in "here document". See Section 3.24.
|
pipe. Passes the output of previous command to next one, or to shell.
This is a method of chaining commands together.
echo ls -l | sh
passes the output of "ls -l" to the shell, with the
same result as a simple "ls -l".
cat *.lst | sort | uniq
sorts the output of all the .lst files and
deletes duplicate lines.
Note: If one of the commands in the pipe
aborts, this prematurely terminates execution of
the pipe. Called a broken pipe,
this condition sends a SIGPIPE
signal. (See Section 3.26 for more detail
on signals.)
>|
force redirection (even if
noclobber environmental variable is in effect). This will forcibly overwrite an existing file.
-
redirection from/to stdin or stdout.
(cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xvfp -)
# Move entire file tree from one directory to another
# [courtesy Alan Cox, a.cox@swansea.ac.uk]
#
# More elegant than, but equivalent to:
# cd source-directory
# tar cf - . | (cd ../target-directory; tar xzf -)
bunzip2 linux-2.4.3.tar.bz2 | tar xvf -
# --uncompress tar file-- | --then pass it to "tar"--
# If "tar" has not been patched to handle "bunzip2",
# this needs to be done in two discrete steps, using a pipe.
# The purpose of the exercise is to unarchive "bzipped" kernel source.
Note that in this context the "-" is not
itself a Bash operator, but rather an option recognized by
certain UNIX utilities.
Where a filename is expected, redirects output to stdout
(mostly seen with tar cf)
Example 3-4. Backup of all files changed in last day
#!/bin/bash
# Backs up all files in current directory
# modified within last 24 hours
# in a tarred and gzipped file.
if [ $# = 0 ]
then
echo "Usage: `basename $0` filename"
exit 1
fi
tar cvf - `find . -mtime -1 -type f -print` > $1.tar
gzip $1.tar
exit 0
-
previous working directory. cd - changes to previous working
directory. This uses the $OLDPWD environmental
variable (see Section 3.7).
Caution
This is not to be confused with the
"-" redirection operator just discussed. How
Bash interprets the "-" depends on the
context in which it appears.
~
home directory. ~bozo is bozo's home directory,
and ls ~bozo lists the contents of it.
~/ is the current user's home directory,
and ls ~/ lists the contents of
it.
White space
functions as a separator, separating commands or variables. White space consists of either spaces, tabs, blank lines, or any
combination thereof. In some contexts, such as variable assignment,
white space is not permitted, and results in a syntax error.
Blank lines
Blank lines have no effect on the action of a script, and are therefore useful
for visually separating functional sections of the script.