These are the Bourne Shell notes --Title: Math 481/581 Lecture 20: Bourne Shell Scripts
Today we'll delve into writing shell scripts using the Bourne Shell.
Command | Function |
---|---|
[ ... ] | See "test" |
awk | Scripting language |
basename | Strip leading dirs from filename |
cat | Print files to stdout |
chmod | Change file access permissions |
cp | Copy files |
cut | Print parts of lines of files |
date | Print current date to stdout |
dirname | Print leading dirs of filename |
du | Show disk usage in KB for dirs |
echo | Print args on stdout |
expr | Perform basic arithmetic |
false | Return nonzero exit status |
fgrep | Print lines of files containing string |
find | Recursive directory search |
grep | Print lines of files matching regexp |
head | Get first N lines of file |
ls | List files in dirs |
mkdir | Create directories |
mv | Move or rename files |
rm | Remove files |
rmdir | Remove empty directories |
sed | Stream editor |
sleep | Pause for a specified interval |
sort | Sort lines in files |
tac | Reverse lines in files |
tail | Get last N lines of file |
tee | Save copy of stdin to file |
test | Test file attributes, etc. |
touch | Set modification time of files |
tr | Translate characters |
true | Return zero exit status |
uniq | Print unique lines of sorted files |
wc | Print # of lines, words, chars in files |
# Send stderr into the void command 2>/dev/null # Print third column of each line in file awk '{ print $3 }' < file # Print total of third column of file awk '{ tot = tot + $3 } END { print tot }' < file # If there are any positional args, treat # them as filenames. Send the contents of # all the files to "whatever". If there # are no positional args, send stdin to # "whatever". # cat $* | whatever # Print second field of colon-delimited file cut -d: -f2 file # Print first 40 chars of each line cut -c1-40 file # Print message to stderr echo "Owie!" 1>&2 # Increment a variable i = `expr $i + 1` # Print paths of all .c files in and below CWD find . -name '*.c' -print # Remove all .dvi files in and below CWD find . -name '*.dvi' -exec rm {} \; # Print names of all .tex files in and below CWD # containing "lemma" find . -name '*.tex' -exec fgrep -l lemma {} \; # Print all lines of file starting with a series of digits grep '^[0-9][0-9]*' file # Print first 20 lines of file head -20 file # Change all occurrences of "foo" to "bar" sed -e 's/foo/bar/g' < file > newfile # Print last 20 lines of file tail -20 file # If file is being written to by another process, # this will show you the updates as they occur tail -f file # Squash uppercase to lowercase tr '[A-Z]' '[a-z]' file > lcfile # Squash multiple spaces to a single space tr -s ' ' file > newfile # Print number of lines in file wc -l diss.tex
#!/bin/sh # # run -- runs commands with optional logging and timing # # function: issue help message and exit usage() { cat << _EOF_ usage: `basename $0` [-a] [-q] [-s] [-fg] [-log logfile] [-c] command -q runs quietly -fg runs job in foreground -a append to logfile -s include date and timing info in logfile -log logs to the specified file -c command follows this script runs commands with optional logging and timing _EOF_ exit 1; } # set defaults for switches APPEND=0; # append to logfile? BG=1; # run in background? LOGFILE=""; # path of logfile QUIET=0; # run quietly? STAMP=0; # include timestamps info? ### process arguments # no args -> help [ $# -ne 0 ] || usage; # got args -- process them while [ $# -gt 0 ]; do case $1 in -h) usage;; -c) break;; -q) shift; QUIET=1;; -fg) shift; BG=0;; -log) shift; LOGFILE=$1; shift || usage;; -a) shift; APPEND=1;; -s) shift; STAMP=1;; *) break;; esac; done # no remaining args = no command = bail [ $# -gt 0 ] || exit 1; # figure out output redirection LOGREDIR=""; if [ x"$LOGFILE" != x ]; then # logging to file... if [ $QUIET -ne 0 ]; then LOGREDIR=">>$LOGFILE 2>&1"; else LOGREDIR="2>&1 | tee -a $LOGFILE"; fi # redirection for timing info TIMEREDIR=$LOGREDIR else # not logging to file -- send to bit bucket if quiet if [ $QUIET -ne 0 ]; then LOGREDIR=">/dev/null 2>&1"; fi; # redirection for timing info TIMEREDIR="" fi # remove log file if we aren't appending [ $APPEND -eq 0 ] && [ x"$LOGFILE" != x ] && /bin/rm -f $LOGFILE; # construct command to execute if [ $STAMP -ne 0 ]; then # include timestamp -- run in subshell CMD="( $*; date ) $LOGREDIR" else # no timestamp -- just run it CMD="$* $LOGREDIR" fi [ $BG -eq 0 ] || CMD="$CMD &" # output starting timestamp if requested if [ $STAMP -ne 0 ]; then eval echo '================================================' $TIMEREDIR eval date $TIMEREDIR eval echo "`basename $0`: $*" $TIMEREDIR fi # execute command (and emit ending timestamp if requested) eval $CMD # success exit 0 # EOF run