IT 244 – Chapter 8 The Bourne Again Shell:

advertisement
IT 244 – Chapter 8
The Bourne Again Shell:

The system we are using is sf05.users.cs.umb.edu (accessible with ssh from
home). This is a Linux system.

Startup Files:
o The shell will look for the first of the following for environment setup:
 ~/.bash_profile
 ~/.bash_login
 ~/.profile
o Other setup files exist for interactive/non-interactive shells, but we
will not be covering these.
o Startup files are the first example of bash programming that we will
do. The topics include:
 Variables
 Conditional Statements
 Functions
 ???
o Running a startup file other than at login – the following will cause the
actions specified in the file to affect the current shell, rather than
forking a new process (no need to be executable):
 Use the ‘.’ (dot) operator, or
 Use the “source” command

Commands:
o Symbol commands:
 () – subshell
 the content is executed in a separate process space
 $() – command substitution
 same as ``, but able to be nested
 (()) – arithmetic evaluation
 like let – the enclosed expression must include an equal
“=” sign.
 $(()) – arithmetic expansion
 no equal sign is used – this is used to substitute the
result of the expansion into another expression or into a
string
 [] – test command
 returns a boolean result, so can be used as the condition
of an if statement, or on its own after which you would
test the $? Variable
 make sure to leave whitespace between this and the
actual test to be evaluated inside it.
 [[]] – conditional expression


 like [] but adds ability to do string comparisons
More about redirecting
o < filename – redirects standard in from filename.
o > filename – redirects standard out to filename.
 If filename exists and noclobber is set, this will not work
 If filename exists and noclobber is not set, then filename will be
overwritten.
 If filename does not exists, then filename is created.
o >| filename – redirects standard out to filename, even if noclobber is
set.
o >> filename – redirects standard out and appends it to filename.
 If filename exists and noclobber is set, this will not work
 If filename exists and noclobber is not set, then filename will be
appended to.
 If filename does not exists, then filename is created.
o &> filename – redirects BOTH standard out and error to filename.
A Simple Shell Script
o Needs to be executable as long as it is not an environment script that
will be run with the ‘.’ (dot) or “source” commands.
 chmod 755 <file>
 NOTE: if you just type /bin/bash <file> then it is not necessary
for the file to be executable (this is slower than the other way).
o Needs to be in the $PATH, or use absolute/relative path to reference.
o #!<full path to shell> - (#!/bin/bash)
 Directive referencing the appropriate shell executable
 Need this so that there is never a question as to which
shell it is written for, and therefore which should run it.
o # - Comment to end of line
o Executing a shell script causes the current shell to fork, which creates
a new process (so that one becomes two).
 The new process is initially a copy of the parent shell.
 The parent shell then tries to exec the script as a command.
 If it were a binary executable, then it would be overlaid
in the duplicate process space and then run.
 Since it is a script, exec will fail, and this tells the parent
shell it’s a script and the shell should exec commands in
the script one by one into the duplicate process space.
o This is basically the same as running each
command from the command line, but the input
passing the commands in is from the script.
o Separating and grouping commands:
 ‘;’ or NEWLINE separate commands.
 ‘\’ continues a command on the next line
 The newline for the continuation will be ignored.
o Both lines will be treated as one, with no added
space.




For bash, a newline in the middle of a quoted string acts
the same way, except that it interprets the newline as a
newline.
‘|’ and ‘&’ separate commands and do something else
 ‘|’ – pipe is as we know it, a connector of standard out to
standard in.
 ‘&’ – backgrounding one command, followed by
whitespace of any kind, allows for another command to
be entered.
o Therefore, the following is legal, and creates
three separated processes in background:
 ls & ls & ls &
() – groups commands and creates a subshell (another
duplicate process that will be exec’ed upon).
 Within this grouping, commands are again separated by
‘;’, ‘|’, or ‘&’, or can be another (nested) grouping.
Parameters and Variables:
o Parameters are named values that can be accessed from within a
script by preceding the name with a ‘$’.
o Parameters whose names consist only of letters, digits, and
underscores, are often called Variables.
o Users can define their own variables for use during the run of a script.
 User defined variables can also be used as environment
settings.
o Setting variables:
 Local/temporary: <varname>=<value>
 NOTE: no whitespace either side of the ‘=’.
 Bash allows for putting variable assignments on a command
line.
 You create the assignment before the command is
called, and when the command is called the variable will
be accessible.
o Keyword Variables:
 Have special meaning to the shell and usually have short
mnemonic names. (PATH, HOME, etc.)
o Positional parameters:
 $? – gives the return status of any command.
 This allows for testing whether a command ran well or
had an error, before going ahead and running the next
command.
 Such testing can be used to either terminate the script,
cause the script to prompt the user for information, or
cause the script to make a decision on the next action.
 $# - gives the number of arguments passed to the script.
 $<num> - command line argument to a script
 $0 is the command name


$1 to $9 are the arguments passed to the script
If more than 9 arguments are passed to the script:
o shift must be used to access more than 9
arguments by shifting the list or values currently
referenced by the 9 variables to the left, which
drops the current value of $1, and moves $2 to
$1, all the way up to moving $9 to $8, and then
moving the next unreferenced argument value as
the value of $9.
o User-created variables:
 Parameter substitution:
 If a variable is referenced (with $) as part of a command
line, or as part of a string (within double quotes), the
shell will interpret that variable and substitute its value,
on the command line or within the string, in place of the
variable name.
o This can be done for all variables, user-defined
or not.
 If whitespace must be part of a string, the string must be
quoted so that all whitespace is kept.
o NOTE: For parameter substitution, if whitespace
exists inside a string variable, and that variable is
passed to a command on the command line, the
content of the variable will be substituted for the
variable name, and THEN, the shell will interpret
the line, which means that the separate
(whitespace-separated) tokens of the string will
be passed in to the command rather than one
string.
 To pass the original string to the
command, you must surround the
variable name with double quotes, ie:
 echo “$string_with_whitespace”
 Assigning pathname expansion to a variable:
 list=max*
o The shell will expand max* to all files in the
current directory that start with the string max.
It will then give that expanded list, as one spaceseparated string, as content of the variable list.
o To echo this variable will display something like
the display given by the command: ls max*
(except that if any of the files is a directory, ls
will list the files inside of that directory).
 unset <varname>
 Will remove the variable from the environment
o ${<var>} – This is the regular way to reference the value of a variable,
but $var is allowed by the bash shell.

This method of retrieving the value is very useful when you are
trying to substitute the value into a string where the variable
name would end just before the next non-whitespace character
of the string, ie:
 echo “$varThis is fun” – will look for a variable named
varThis, when you meant the variable named var.
 echo “${var}This is fun” – will find the variable named
var and substitute that just before the word This.

Variable Attributes:
o readonly <varname>=<value> - creates a readonly variable
 NOTE: you cannot create the readonly variable with no value,
and the set its value on the next line. It MUST be given its value
at the time it is created if created with the keyword readonly.
o Export <varname>=<value> - creates a global variable
 A global variable is accessible by any command or function in
this shell or any child of this shell.
o Other ways to create variables with special attributes:
 declare and typeset both do the same thing
 declare <options> <varname>
o Options (the first three are exclusive of each
other):
 -a - array
 -f - function
 -i - integer
 -r - readonly
 -x – exported
o If use the + character instead of – for the option,
you will remove the attribute on the variable.
o Special (keyword) Variables
 HOME
 PATH
 PS1 – User prompt
 PS2 – User secondary prompt (continuation)
 PS3 – Prompt for select command
 PS4 – Prompt for bash debugging option
 IFS – Internal Field Separator (one ore more characters)
 Defines the default separator, which is normally
whitespace (space, tab, newline).
 This is the separator that the shell uses to split the
command line.
o Try: IFS=”:”; this=hello:::there; echo $this; cat
$this
 CDPATH – allows for giving subdirectories and these will all be
searched if the subdirectory has not yet been found.

More on Processes:
o Just as there is a ps command to show all processes:
 There is a pstree to show the tree of child processes from init
which is the process with id 1. (pstree –p shows process ids).

Job Control revisited:
o When you use Ctrl-Z on a running process, the process is suspended.
 You must then type bg <job#> to resume it in background.

History
o List of preceding commands (events) kept for quick re-entry
o Variables:
 HISTSIZE – the number of preceding events that will be
remembered for this session (default 500 events).
 HISTFILE – the file that keeps the preceding commands
(default !/.bash_history)
 HISTFILESIZE – the number of preceding events that will be
remembered between sessions (default 500 events).
o Re-execution
 history – gives the list of the whole history file
 history <num> - gives the last num worth of the history file.
 fc (fix command)
 -l – shows the last 16 commands
 -l [first [last]] – shows the commands between the given
range, or from the given first to the most recent.
 -l [firststring [laststring]] – same but with strings that
start the command line.
 -e <editor> - Use this editor
o If FCEDIT is set, then –e is not necessary
o If FCEDIT is not set, then without –e nothing
happens unless an first/last is given.
o NOTE: after an edit, a ‘q’ doesn’t stop the
commands from running. The only way is to
clear the whole buffer and save it.
 -s – runs without editing in the case that FCEDIT is
given.
 !<number> - re-executes the command with history number
<number>.
 !-<number> - re-executes the command <number> commands
back.
 !<string> - re-executes the first previous command starting
with the given string.
 !?<string>[?] – re-executes the first previous command
containing the given string. The final ? is optional.
 !! – executes the last run command
 !# - anywhere in the current command line will duplicate the
current command line.
 ls; !# !# !# !# !# !#
I will not be going over the word designators, but they are
interesting and you should take a look.
o The Readline Library
 Configuration by creating/editing the ~/.inputrc file.
 If you don’t want readline being used, then start bash
using the –-noediting option.
 set –o vi / set –o emacs
 setting the editor for the readline library
 Many of the keystrokes that you can do in vi can be done on the
single command line after an <esc>.
 / - will do searches the same way
 Arrows work the same way, as do the letter keys
 <num><Shift-G> will go to the history line
 try it out
 Command completion – tab completes according to the PATH
variable.
 Pathname completion – tab completes according to the path or
filename given.
 Variable completion – tab completes according to the variables
in the current environment, with the variable preceded by $.


Aliases
o Alias [name=[value]] – no spaces allowed either side of the = sign.
o Variables in aliases – surround the alias string (including the variable
preceded by a $) with single quotes.
 Double quotes allows the shell to expand the variable at the
time the alias is being created, so the alias does not contain a
variable as a result.
 Single quotes does not expand, so the alias string contains a
variable which gets expanded at the time the alias is run.

The Directory Stack:
o Allows for very fast movement between commonly used directories.
 dirs – Displays the current stack.
 pushd <directorypath> – Puts the given directory (absolute or
relative path) on top of the directory stack and changes the
shell’s working directory to that directory.
 pushd with no argument will act like “cd –“.
 pushd +<num> - Accesses another directory on the
stack other than the top directory, moves that to the
top, and changes the shell’s working directory to that
directory.
o NOTE: the topmost directory on the stack is
numbered 0, and increments on down the stack.
 popd – Removes the topmost entry on the stack and changes
the shell’s working directory to that directory.

popd +<num> - removes another directory on the stack
other than the top directory.
o NOTE: with a +<num> argument, popd will not
change to that directory, but will only remove it
from the stack.

Functions
o Like calling a script, but there much faster, and no overhead of forking
a subshell.
o Functions that are declared on the command line can be removed by
giving the unset command the function name.
[function] function-name()
{
commands
commands
}
o Commands in a function can be anything you could have in a shell
script, or a call to a function.
o The break statement terminates the function before it has ended.
o Functions are good for:
 Cleaning up code by giving names to smaller amounts of code
that can be called from anywhere inside the shell script.
 Allows for breaking the script up into logical units.
 Creating your own commands by defining functions in your
startup script so that they are available during your shell
session.

Bash features and options
o set [+|-]o <feature> - on/off
o shopt –[s|u] <feature> - set/unset
 Pages 331 through 333 gives a pretty good list. Some are
controlled by set, and others by shopt.
 Shopt has a –o option that allows for setting features
otherwise done using set.
o Features:
 noclobber
 allexport (off by default)
 history (on by default)
 emacs as line editor (default is no line editing)
 vi as line editor (default is no line editing)
Processing the command line
o The following order is used in processing the command line:
 Bash reads the entire command before processing it
 If the command is multi-line, bash will recognize this
and wait until it has read all the lines of the command
before processing.
 History Expansion





!<string>, or !! will cause the command line to expand
into the matched command line in history.
Alias Substitution
 If the first word of a simple command matches an alias
in the environment, that alias is substituted instead of
that word.
o shopt –u expand_aliases
 turns aliases off
Parsing and Scanning the command line
 The shell the parses the command line separating
tokens by the IFS characters.
o NOTE: If IFS is unset, the bash shell using spacetab-newline as its default.
o The shell then scans each token for special
characters and patterns for further expansion.
This is command line expansion.
Command line Expansion
 Brace Expansion
o On by default – turn it off with set +o
braceexpand.
o Echo chap_{one,two,three}.txt becomes
chap_one.txt chap_two.txt chap_three.txt
o The comma-separated brace list is expanded into
a space-separated list of strings. The preamble
and postscript are attached to each expanded
instance from the list.
o Can be used for copying files with long names
where most of the name is the same.
o Can be used to created directories that are
mostly the same. This is a good situation where
no files exist for filename expansion to occur.
 You cannot create new names using the [ ]
ambiguous file reference.
 Tilde Expansion
o For a word starting with a tilde, the shell looks
passed the tilde to find either an IFS character or
a /. The / must come directly after the ~.
 If the ~ is followed by an IFS character or
is directly followed by a /, the expansion
is to the current user’s full path home
directory.
 If the ~ is followed by a string and then an
IFS character, the string is taken to be a
user name, and the shell will attempt to
expand the ~ with that user’s full path
home directory.





If this ~<string> is followed by a /,
the shell will give an error
message.
 ALSO: ~+ means PWD, and ~- means
OLDPWD
Parameter and variable expansion
o When a $ is found, it must be followed by a
string, or by one of the allowed system-level
parameter character sets, terminated by an IFS
character.
Arithmetic expansion
o If the $ is followed by ((, then arithmetic
expansion takes place. (Command substitution
with $() is dealt with below).
 The shell searches for the next )), and
treats the embedded string as an
arithmetic statement and gets evaluated.
 All Arithmetic in bash is integer.
 Variable names in an arithmetic
expression do not need a $ preceding.
 The result of the expansion is substituted
in the place of the $(()) expression.
 You can use command substitution inside
an arithmetic statement, as long as the
result of the command is a string that can
be converted to an integer.
o The let command can also be used to evaluate an
arithmetic expression for an assignment to a
variable
 let “numpages=$(wc –l < ltr.txt)/66 + 1”
 here, the quotes keep the
expression from being broken into
tokens because of the spaces.
Command substitution
o $() or ` ` (the second one is older, and doesn’t
allow for nesting and needs to be escaped in
some cases)
 echo $(pwd) same as echo `pwd`
 This script:
 where=$(pwd)
 echo “You are in $where”
 Or just
 echo “You are in $(pwd)”
 echo “You are in `pwd`”
 ls –l `find . –name README –print`
o See page 341 for a nested example
Word Splitting

o All of the results of the above expansions can
possibly be further split using IFS characters.
 Pathname expansion
o Finally, after all of the above, the shell looks for
ambiguous file references (*, ?, [ ])
 If no file with the given pattern is found,
the pattern is left as it is.
 Ambiguous file expansion will end up
with either the unexpanded pattern, or a
list of one to many non-ambiguous
filenames, each starting with the given
directory if one was given.
 NOTE: a period starting a filename, or
following a / must be matched explicitly.
o Quotation marks are used to save spaces, and in
the case of single quotes, to stop expansion of
special characters.
 If a variable has been created with special
characters in it, using that variable on the
command line without double quotes will
cause the special characters to be
expanded.
 Process substitution
o Finally, the shell is able to process the |, >, and <
redirection operators for process substitution.
o This means that the shell substitutes the input
and output devices according to pipes
After all these expansions have been completed, the shell
removes from the tokens any single/double quotations, and
backslashes that didn’t result from an expansion.
Download