Introduction

This lab will give you some experience writing shell scripts.

You will need to sign in to https://git-classes.mst.edu and clone the repository for this lab.

Your repository will be named something along the lines of 2017FS-<section>-lab04-<username>1. Make sure to clone with the HTTPS URL (unless you’ve set up SSH keys).

Feel free to consult with your favorite search engine, relevant man pages, the lab instructor and assistants, and your fellow labmates when you need help.

Just make sure that what you turn in is your own work!

I strongly advise you to experiment and to test your code as you go along! Bash is a little weird, so checking to make sure it’s doing what you think it is is important.

Problem 0: Clean up after yourself

You’ll notice that this repository doesn’t have a .gitignore file. This time, it’s your responsibility to make sure you don’t commit junk to your repository. We don’t want to see…

  • Compiled files
  • Editor backup files
  • Other crumbs (like .DS_Store)

Note that there’s nothing you need to do for Problem 0. You’re welcome (read “encouraged”) to create a .gitignore to help keep things clean.

We will, however, ding you for leaving junk in your repository when we grade.

Problem 1: Big Trouble with Little Whitespace

For this problem, you will be experimenting with a bash script. Be sure to answer all of the questions below and store your responses in a file called answers.txt.

Setup

  1. Create a new bash script called compiley.sh, add the content below, and save it.

    #!/bin/bash
    
    compile_file() {
        INPUT="$1"
        OUTPUT="$2"
    
        echo ""
        echo "Function parameters"
        echo "- compile_file's first parameter (\$1) is \"$1\""
        echo "- compile_file's second parameter (\$2) is \"$2\""
        echo "- \$INPUT is \"$INPUT\""
        echo "- \$OUTPUT is \"$OUTPUT\""
        echo ""
    
        g++ -o "$OUTPUT" "$INPUT"
    }
    
    echo "Positional parameters:"
    echo "- First positional parameter (\$1) is \"$1\""
    echo "- Second positional parameter (\$2) is \"$2\""
    echo "- Joined positional parameters (\$@) is \"$@\""
    
    compile_file $@
    
  2. Create a simple, compilable C++ file2 and save it. Name it program.cpp.

  3. Create a file called answers.txt and put your name at the top.

Questions

  1. Use compiley.sh to compile program.cpp into an executable named hello.
    1. What is the command you ran in order to compile program.cpp to hello using compiley.sh?
    2. Briefly describe how the script works in plain English. (You don’t need to explain the echo’s.)
  2. Rename your program to my program.cpp3 by running mv program.cpp "my program.cpp". You can run ls -l to make sure your file name has that space in it.
    1. Can you still compile your program with compiley.sh?

      # Don't forget to escape the space when you run the script!
      $ bash compiley.sh my\ program.cpp hello
      
      # Or, you could use quotes
      $ bash compiley.sh "my program.cpp" hello
      
    2. Based on the output and g++ error messages, what is the problem?

  3. Change the last line of compiley.sh to compile_file '$@' and try compiling your program again.
    1. Does compiley.sh work now?
    2. What’s the problem this time?
  4. Change the last line of compiley.sh to compile_file "$@" and try compiling your program again.
    1. Does compiley.sh work now?
    2. Why did the double quotes (") fix the problem?

Problem 2: Your Own (Terrible) Search Engine

Write a bash script named goog.sh that counts the occurrence of a string in the source of a web page.

Here are some examples:

# Look for "Jake" on the specified web page
$ bash goog.sh Jake http://dsl.mwisely.xyz/labs/3/assignment/
Jake: 11

# Look for "the" on the specified web page
$ bash goog.sh the http://dsl.mwisely.xyz/labs/3/assignment/
the: 43

# Look for "The" on the specified web page
$ bash goog.sh The http://dsl.mwisely.xyz/labs/3/assignment/
The: 2

# Look for "cake" on the specified web page
$ bash goog.sh cake http://dsl.mwisely.xyz/labs/3/assignment/
cake: 0

# Give it the wrong number of arguments to see the usage
$ bash goog.sh
Usage goog.sh WORD WEBSITE

Expected Behavior

  • Your script always takes exactly 2 arguments:
    • The string to search for
    • The URL of the website we’re looking at
  • If the user misuses your script, it should show them the usage.
  • The program must print the number of times the word appears in the web page’s source (case sensitive!)

Requirements and other Hints

  • You’re going to need an if-statement to check the arguments.
  • You can exit your program using exit NUM where…
    • If NUM is zero, that implies that your program ended without error.
    • If NUM is non-zero, that implies that the program ended due to an error.
  • The following things should be (very) useful:
    • echo can be used to print messages (including variables) to standard out.
    • wget downloads web pages.
      • The -O flag can be used to direct downloaded content to standard out.
      • The --quiet flag can suppress ugly download progress.
    • tr translates characters
      • For this program, we want all words on their own lines.
      • We can use tr to translate all " " (space characters) to "\n" (newline characters)
    • grep searches for occurrences of a string pattern
      • The -c flag asks for a count of the number of lines containing a match.
      • We need tr to put every word on its own line since grep counts the number of lines that match.
  • You’re going to want to use a couple pipes (|) to redirect output.

Problem 3: Menus!

Make a shell script named menu.sh that loops through all files in the current directory, and for each file, prints out a menu:

v) View file
e) Edit file
c) Compile file
q) Quit

Then the script gets the user’s choice and does it. Consult the following list to see what ‘it’ is:

  • View file: Open the file with less
  • Edit file: Open the file in jpico
  • Compile file: Compile the file with g++
  • Quit: End the program with exit
  • Anything else: Print an error message and go to the next file
# Let's say the directory contains file.cpp, file.h, goog.sh, and menu.sh
$ bash menu.sh
v) View file.cpp
e) Edit file.cpp
c) Compile file.cpp
q) Quit
e

v) View file.h
e) Edit file.h
c) Compile file.h
q) Quit
v

v) View goog.sh
e) Edit goog.sh
c) Compile goog.sh
q) Quit
INVALID RESPONSE

Skipping this file!

v) View menu.sh
e) Edit menu.sh
c) Compile menu.sh
q) Quit
q

Expected Behavior

  • Your script should take no additional command line arguments

Requirements and other Hints

  • Your script needs to define at least one function
  • Your script should use a case statement
  • You can prompt the user for input4 using read

Epilogue

As with lab 3, your git repo on http://git-classes.mst.edu is your submission. Don’t forget to commit and push all relevant files. Make sure you see everything you expect on GitLab!

We expect to see the following files on your master branch:

  • README.md
  • answers.txt
  • goog.sh
  • menu.sh
  • .gitignore if you chose to make one
  1. … where <section> is your section (a or b) and <username> is your username. 

  2. A hello world program is perfectly fine. It just needs to be something that g++ can compile. 

  3. There’s a space there!!! 

  4. cin style.