The shell has a full featured if very weird programing language. It has variables, control structures, and input-output methods.
Why: People use bash not because it is the best progfaming language around (it's not) but because it is something of a standard. All UNIX machines have bash. Many important system scripts are written in bash (/etc/rc.d/* for instance).
The Start of the Program: All shell programs should start with the line "#!/bin/bash". This tells the kernel to hand the script to /bin/bash, and not to try and run it as if it were a binary. Also, don't forget to set the execute bit.
Variables: You can use any reasonable variable name. All variables are of type 'string'. You never need delcare a variable before use. To get the value of a variable, put a "$" in front of it. To set a value, omit the "$". for instance ...
a=4 echo $a
Control Structures: Bash has all the standard control structures. Notice that the if stuff is somewhat weird. For instance ...
while [ $a = 4 ]; do echo $a done for a in /usr/bin/* do rm $a done if [ $a = 4 ]; then echo Hi There fi if [ $a = 4 ]; then echo A is four else echo A is not four fi if [ $a = 4]; then echo A is four elsif [ $b = 4 ]; then echo B is four fi
Arithmetic Expressions: You will rarely need these, but here they are. Do math by running the expr program. Spaces are REQUIRED around all operands and operators of an expression. Remember that '*' is a reserved symbol.
let a=$a+1
a=`expr 3 +$a`
Boolean Tests: There are a million of these. See
"man test" for more details. Here are some examples
Less than |
$a < $b |
Greater than |
$a > $b |
File Exists |
-f $file |
Dir Exists |
-d $dir |
Special Variables
There are many variables automatically set by the shell for your
use. These variables normally are read only, and tell useful
things abut the state of the system.
PWD |
The present working directory |
SHLVL |
Shell level -- incremented one each time -- great for recursion |
UID |
The User ID of the current user |
LINENO |
The line number currently running -- Use for debuging |
PATH |
The search path for commands |
HOME |
The home directory |
CDPATH |
The search path for the CD command |
PS1 |
The primary shell prompt |
PS2 |
The secondary shell prompt -- only used when you press return inside a quoe or block |
PROMPT_COMMAND |
A command that runs every time a primary prompt is displayed |
noclobber |
The shell will refuse to overwrite a file with ">". |
$$ |
The current process IS of the shell -- used for temporary files |
Temporary Files
It is a programing mistake to hardcode
temporary filenames in a shell script. Consider what might
happen if two people run the script at the same time! Instead,
use "$$" to make each name unique. For instance,
don't use the temporary file "/tmp/backup", use
/"tmp/backup.$$".
Doing math in Bash
There are lots of ways. See https://www.shell-tips.com/2010/06/14/performing-math-calculation-in-bash/. But really, when you can just use 'let'.
Fake Input and Fake Output
Sometimes you
will want to run a program, but not want to see it's output.
Luckily, and data sent to the special device /dev/null will be
ignorred. Other times a program insists on reading data, but
will happily accept all zeros. The special file /dev/zero
consists of an infinite number of zeros. For example
funnyprogram < /dev/zero > /dev/null
Redirecting Errors
You can redirect an error message
with "2>". This is a great way to build log files
of errors. For example, to run ls but not see any error messages, try
ls /alfj /tmp 2> /dev/null
Lists
One neat trick is to make a 'list' and then get
data from the 'list'. For example,
(cd
/home; tar cf - . ) | ( cd /newhome; tar xf - )