Based on previous materials by Dr. Robert Kline
1
2
3
4
5
6
7
8
9
10
11
12
|
- In your CloudLab experiment, run the following:
```bash
sudo su - seed
wget https://cs.wcupa.edu/lngo/assets/src/bash_basics.zip
sudo apt-get update
sudo apt-get install -y unzip
unzip bash_basics.zip
cd bash_basics
ls
|
1
2
3
4
5
6
7
8
9
|
- Bash script files can be named as you like. Unlike Windows systems,
the extension is not an essential feature which determines the usage.
The `.sh` extension is merely a convention which can assist editor
recognition. All scripts can be executed explicitly using the bash executable:
```bash
bash SOME-SCRIPT.sh
|
1
2
3
4
5
6
7
8
|
- The file itself must be executable by you.
- If you are the owner of the script you can add that
permission with statements like:
```bash
chmod +x SOME-SCRIPT.sh
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
## 2. The Bash Language
- The Bash language has three main functions:
- execute commands interactively
- extend the set of commands via scripts
- build up, via sourcing, the user environment with variables, aliases, functions
- In particular, Bash, per se, is not a general purpose programming script language
like, say, Perl, Python or TCL.
- Its main orientation is towards executing the standard UNIX command set and Bash scripts
rely heavily on the standard UNIX commands.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
## 3. Variables and Values
- The program `scalars.sh` illustrates basic principles of
Bash variables and values. In particular, the only scalar data
type is a string. Values are created in several ways:
- within uninterpolated quotes: ' '
- within interpolated quotes: " "
- the output of a command within shell evaluated back quotes $`\_`$ or within `$( )`
- a bareword which is not a Bash reserved word and contains no special operator
characters
|
1
2
3
4
5
6
7
8
|
- Although echo is the most common output statement, Bash
also supports the C-style printf statement, e.g.,
```bash
printf "num=%05d\n" 27
echo AFTER
|
1
2
3
4
5
6
7
8
9
10
11
12
|
## 4. More about Bash
- Bash, just as other languages, does support additional structured data types in the
form of lists and maps (associative lists).
- It also provides a way of assigning a type to a variable through a the declare
statement. View and execute the following script for observation
```bash
more scalar-declares.sh
./scalar-declares.sh
|
1
2
3
4
5
6
7
8
9
10
11
12
|
- One of the primary purpose of the bash language is to extend the set of
commands. For this reason Bash provides simple access to the command-line
parameters. Bash uses the variables `$1`, `$2`, etc. The expression `$0`
is the command name itself. They should be double-quoted. Use these test-runs:
```bash
$ more args.sh
$ ./args.sh
$ ./args.sh a b c
$ ./args.sh "a b" c
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
## 5. Bash condition
- The bash if-else syntax is unusual compared to other languages.
The format looks like this:
```bash
if ...
then
some statements
elif ...
some statements
else
some statements
fi
|
The “…” sections represent boolean “tests”. The chained elif and the else parts are optional. The “then” syntax is often written on the same line as the if portion like this: if ...; then
1
2
3
4
5
6
7
|
```bash
more pingtest.sh
./pingtest.sh
./pingtest.sh 8.8.8.8
./pingtest.sh 2.2.2.2
|
1
2
3
4
5
6
7
8
|
- What is considered as boolean expression in an if test uses this syntax:
```bash
if [ BOOLEAN-EXPRESSION ]; then
statements ...
fi
|
1
2
3
4
5
6
7
8
9
10
11
12
|
- A number of common Bash constructions use the unary "–" prefix file test operators, e.g.,
- `-e` NAME: NAME exists as a file (of some type)
- `-f` NAME: NAME exists as a regular file
- `-d` NAME: NAME exists as a directory
- An example of this appears in the `~/.bashrc` startup script:
```bash
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
- The `if` operator (and other tests) can be used with boolean expressions
using appropriate syntax.
- The test expressions are normally within single brackets [ .. ].
- There is a single space after `[` and before `]`.
- Within these we have these operator usages:
- `=`, `!=`: lexicographic comparison
- `-eq`, `-ne`, `-lt`, `-le`, `-gt`, `-ge`: numerical comparison
- However both double brackets `[[ .. ]]` and double parentheses `(( .. ))`
can serve as delimiters.
- The operators `<` and `>` normally represent *file redirection*,
but can be used for lexicographic comparison, within `[[ .. ]]` and numerical comparison within `(( .. ))`.
- You can view and observe some examples from: `test-values.sh`
```bash
more test-values.sh
./test-values.sh
|
1
2
3
4
5
6
7
8
|
- The way Bash deals with strings has certain unexpected consequences.
Consider the program `errors.sh`:
```bash
more errors.sh
./errors.sh
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
- Bash uses primitive globbing patterns for various matching operations.
- The most common is the usage of `*` which matches any sequence of characters.
- Less common is `?` which matches any single character and even less common are
character sets, such as `[A-Z]` and `[^0-9]`.
- These type of expressions stand in contrast to more powerful regular expression
pattern generators which, in Bash, are only available through auxiliary commands.
- Glob patterns are simple, familiar patterns such as those used commonly in file listing:
- `ls *.html` # all HTML files (not starting with ".")
- `ls .??*` # all dot files except "." and ".."
- `ls test[0-3]` # "test0", "test1", "test2", "test3"
- The Bash `case` statement distinguishes itself from an `if/else`
constructions primarily by its ability to test its cases by matching
the argument against glob patterns. The syntax is like this:
```bash
case "$file" in
*.txt) # treat "$file" like a text file
;;
*.gif) # treat it like a GIF file
;;
*) # catch-all
;;
esac
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
## 6. Bash loop
Bash has both for and while loops. However, the type of control for these is typically not numerical. The most common looping structure in Bash is the for/in structure like this:
for x in ...
do
statements involving $x
done
Loops
The "..." is a list of things generated in a number of ways. The x is the loop variable which iterates through each item in the list. For example, try running this program in the current directory:
$ more fileinfo.sh
$ ./fileinfo.sh
In this case the things iterated are the files in the current directory.
Loops
One can use numerical-like looping with the double-parentheses like those in for numerical comparison:
for ((i=1; i<=10; ++i)); do
echo $i
done
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
- Command-line arguments commonly consist of option arguments
beginning with a "-". Consider, for example, the follow `unzip` command
which extracts `FILE.zip` into `/usr/local`,
- doing so with no output (-q) and
- overriding existing files (-o).
- The FILE.zip portion is the argument and others are options.
- Some options, like -d, take an argument themselves.
- The unzip command takes many more options (mostly prior to the argument).
```bash
unzip -q -o FILE.zip -d /usr/local
|
1
2
3
4
5
6
7
8
9
10
|
## 7. More Bash
- The Bash language itself has very unintuitive string-processing operations.
Later we'll see how to use UNIX commands to do string processing.
```bash
more string-processing.sh
./string-processing.sh
|
1
2
3
4
5
6
7
8
|
- Functions offer an improvement of aliases. They must be defined before being used. In practice, they are often grouped into Bash files which are sourced within the script which uses them.
- Functions are supposed to emulate the way commands work. They do not return values in the usual way; any value sent back by the return statement must be an integer which acts like the exit code of an executable.
```bash
more functions.sh
./functions.sh
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
- The Bash language relies heavily on the UNIX-like environment in which it resides in order to create utility scripts. This environment includes many standard UNIX string processing operations such as these:
- `sed`: (stream editor) for regular-expression substitution
- `grep`: can be used to perform match testing with -c (count) option; the -e option uses regular expression instead of glob patterns
- `awk`: captures the fields of a line (separated by whitespace) and does operations on these fields;
- `tr`: translate from one list of characters to another; often used to convert case of a string
- `sed`, `grep`, `awk`, and `tr` are used in Bash via standard I/O. All above operations act on text files when given file name as a parameter, or act from standard input with no arguments.
- A common bash expression which uses an external OPERATION to compute some internal value
looks something like this: `result="$(echo "input string" | OPERATION)"`
- The pipe operator "|" is crucial for passing the input string to OPERATION via echo.
The following program illustrates some of these external operations.
```bash
more string-operations.sh
./string-operations.sh
|