Exercises

Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting
Prev |  | Next

# Appendix O. Exercises

The exercises that follow test and extend your knowledge of scripting. Think of them as a challenge, as an entertaining way to take you further along the stony path toward UNIX wizardry.

On a dingy side street in a run-down section of Hoboken, New Jersey,
there sits a nondescript squat two-story brick building with an inscription
incised on a marble plate in its wall:
`Bash Scripting Hall of Fame`.
Inside, among various dusty uninteresting exhibits is a corroding,
cobweb-festooned brass plaque inscribed with a short, very short
list of those few persons who have successfully mastered the material
in the Advanced Bash Scripting Guide, as evidenced by their performance
on the following Exercise sections.
(Alas, the author of the ABS Guide is not represented among the exhibits.
This is possibly due to malicious rumors about lack of credentials and
deficient scripting skills.)

# O.1. Analyzing Scripts

Examine the following script. Run it, then explain what it does. Annotate the script and rewrite it in a more compact and elegant manner.

       1 #!/bin/bash
       2
       3 MAX=10000
       4
       5
       6   for((nr=1; nr<$MAX; nr++))
       7   do
       8
       9     let "t1 = nr % 5"
      10     if [ "$t1" -ne 3 ]
      11     then
      12       continue
      13     fi
      14
      15     let "t2 = nr % 7"
      16     if [ "$t2" -ne 4 ]
      17     then
      18       continue
      19     fi
      20
      21     let "t3 = nr % 9"
      22     if [ "$t3" -ne 5 ]
      23     then
      24       continue
      25     fi
      26
      27   break   # What happens when you comment out this line? Why?
      28
      29   done
      30
      31   echo "Number = $nr"
      32
      33
      34 exit 0

---

Explain what the following script does. It is really just a parameterized command-line pipe.

       1 #!/bin/bash
       2
       3 DIRNAME=/usr/bin
       4 FILETYPE="shell script"
       5 LOGFILE=logfile
       6
       7 file "$DIRNAME"/* | fgrep "$FILETYPE" | tee $LOGFILE | wc -l
       8
       9 exit 0

---

Examine and explain the following script. For hints, you might refer to the listings for find and stat.

       1 #!/bin/bash
       2
       3 # Author:  Nathan Coulter
       4 # This code is released to the public domain.
       5 # The author gave permission to use this code snippet in the ABS Guide.
       6
       7 find -maxdepth 1 -type f -printf '%f\000'  | {
       8    while read -d $'\000'; do
       9       mv "$REPLY" "$(date -d "$(stat -c '%y' "$REPLY") " '+%Y%m%d%H%M%S'
      10       )-$REPLY"
      11    done
      12 }
      13
      14 # Warning: Test-drive this script in a "scratch" directory.
      15 # It will somehow affect all the files there.

---

A reader sent in the following code snippet.

       1 while read LINE
       2 do
       3   echo $LINE
       4 done < `tail -f /var/log/messages`

He wished to write a script tracking changes to the system log file, `/var/log/messages`. Unfortunately, the above code block hangs and does nothing useful. Why? Fix this so it does work. (Hint: rather than redirecting the `stdin` of the loop, try a pipe.)

---

Analyze the following "one-liner" (here split into two lines for clarity) contributed by Rory Winston:

       1 export SUM=0; for f in $(find src -name "*.java");
       2 do export SUM=$(($SUM + $(wc -l $f | awk '{ print $1 }'))); done; echo $SUM

Hint: First, break the script up into bite-sized sections. Then, carefully examine its use of double-parentheses arithmetic, the export command, the find command, the wc command, and awk.

---

Analyze Example A-10, and reorganize it in a simplified and more logical style. See how many of the variables can be eliminated, and try to optimize the script to speed up its execution time.

Alter the script so that it accepts any ordinary ASCII text file as input for its initial "generation". The script will read the first `$ROW*$COL` characters, and set the occurrences of vowels as "living" cells. Hint: be sure to translate the spaces in the input file to underscore characters.

Prev | Home | Next
Converting DOS Batch Files to Shell Scripts |  | Writing Scripts