Bash
From UC_Chemistry
A Bash tutorial for computational chemists. Common recipes for setting up login shells on clusters will constitute another document.
Contents |
Introduction
I came to know bash by way of old manuals for UNIX dating from the time of the Bourn Again Shell's predecessor, sh. Since then, I have added to my knowledge with the help of the manpage and several other good (and usually sparse) references when I needed to get something done. Since I suspect that most people like myself can only learn one thing at a time, while they are in the business of trying to get it done, I am collecting useful recipes on this page in the hope that it can serve as a reference and a learning tool.
This document will thus follow some loose overall structure going from high to low-use bash syntaxes and then high to low-use utilities commonly used to get things done in the shell world. Each entry should contain a couple of examples for the impatient followed by some explanation of what the above has just done to your system if you ran it before reading further and then some comments on how to play around with the syntax so that we can learn by experimentation.
Syntax
Shell / Environment Variables
Setting and displaying:
a=value echo $a export a
Conditional Execution
Ands and or-s:
mkdir /root/cant_do_it || echo "Could not create directory." echo a && echo b || echo c grep -q "alias" ~/.bashrc || ! echo "No aliases." && echo "Aliases found"
The above show how to use simple one-line logical ands, ors, and nots to make statements that execute intelligently. Most commands return true on success and false on failure. A conceptual caveat is that the actual return value for success is zero, and failure is nonzero. For those of you who know any programming language, this is counter-intuitive (opposite to convention), so it is better to think of return values in terms of success = true, faulure = false. A good way to experiment with the above is by replacing the commands with others of your own choosing, possibly including parentheses. The last example gives a nice way to find out if a file contains the word "alias" in it. Grep -q doesn't print out matching lines, but returns true if it found the pattern. Echo always returns true, so its value has to be negated so that only one of the last two statements will execute. This example is not yet idiot-proof, since the file ~/.bashrc may not exist.
if [ "xa" = "xb" ]; then
echo "true"
else
echo "false"
fi
for example
#!/bin/bash COUNTER=0 while [ $COUNTER -lt 10 ]; do echo The counter is $COUNTER let COUNTER=COUNTER+1 done
This is the standard if-then-else clause. You can leave out else if you want. If-then clauses must always be terminaref by fi (if backwards).
var="-k"
case "$var" in
"-k")
echo "Kicking molecule..."
~/bin/kick $molecule
;;
"-a")
echo "Adding molecule to output."
cat $molecule >>$output
;;
"-f")
echo "Finished program."
exit 1
;;
*)
echo "Unrecognized option: $var"
;;
esac
These switch statements are very useful for interpreting command line options inside shell scripts, where they are usually preceded by a call to getopt to parse the options and/or combined with "while [ $# -gt 0 ]" and shift to loop through all arguments. Note that each matching clause contains a list of commands to be executed by the shell and must be terminated with two adjacent semicolons (except for the last clause) and that the whole section is terminated by case spelled backwards.
Streams / Pipes
a | b a | b | c | ...
Loops
For Loops
for i in *; do echo $i [ -r $i.test ] && echo "Found $i.test" done
Utilities
Directory Operations
"ls" the following will list the directory size and the size of each file in human readable format.
$ ls -lh
"test" or "[]" the following example will output "readable" if myfile1 is readable
$ if [ -r myfile1 ];then echo readable; fi
This uses find to locate all files below the current directory "." with size less than 10kB:
find . -size -10k
File Operations
Note that most command line tools can accept input from a file or stdin.
$ cat filename $ cat filename | head
Print the contents of the file to stdout. The pipeline connects the stdout of any previous program to the stdin of the next.
$ head -20 filename
Print the first 20 lines of a file.
$ tail -10 filename
Print the last 10 lines of a file.
$ more filename $ less filename
Read the file in your terminal window.
$ sed -e '--sed script here--' infile >outfile
Run sed on the input file and send the output to a new file. For script details, see the Sed page.
$ cat filename | tr "[:upper:]" "[:lower:]"
Translate characters appearing in set 1 (upper) to those in set 2 (lower). tr only accepts input from stdin...
String Operations
echo
Useful options: -n You can use any of the file operations above with echo if they also accept input from stdin, as in echo "string" | ... .
basename /home/user/test.var .var
dirname
References
- Bash in a Nutshell
- Tutorial from Jialong He at Arizona State
- System admin. book.
- Bash by example from IBM
