CS253: Software Development with C++

Spring 2021

Bash

Bash Lab                

Introduction                

For this lab, you will take a small bash script called rn, modify it to do more things, and turn it in for credit.                 

A script                

A bash script (or more generally, a shell script) is a series of bash commands in a file. You create the file using an editor, such as vim or nano, and then you execute (or run) the script, as if it were a program, because it is one.                 

Really, that’s all there is to it. Anything that you could type into an interactive bash shell (cd, ls, pwd, cp, mkdir, rm, make, vim, etc.), you can put into a bash script.                 

Also, bash scripts often contain other constructs more often found in programming languages, such as if, while, and for statements, and variable usage. You could use such things interactively, but you rarely do.                 

Basic bash programming                

       
if (( $# == 0 ))
then
    echo "I have no arguments. ☹"
fi
    
echo Wildcard: /etc/host*
echo "Quotes protect it: /etc/host*"
Wildcard: /etc/host.conf /etc/hostname /etc/hosts
Quotes protect it: /etc/host*
    
echo "I am $USER"
I am cs253
    
echo 'Cost: $0.24'
Cost: $0.24
    
alpha="foo bar"
echo "I say $alpha"
I say foo bar
    
now=$(date)
echo "Current time: $now"
Current time: Tue Apr 16 17:22:40 MDT 2024
    
let beta=2+2
echo "beta is $beta"
beta is 4
    if condition
    then
        statements
    fi

    
if [[ -e /etc/hostname ]]   # Does the file exist?
then
    cat /etc/hostname       # Let’s see it!
fi
beethoven
    if condition
    then
        statements
    else
        statements
    fi
    if condition
    then
        statements
    elif different-condition
    then
        statements
    else
        statements
    fi
    while condition
    do
        statements
    done
    for variable in list
    do
        statements
    done
    
for person in John Paul George Ringo
do
    echo $person was one of the Beatles
done
John was one of the Beatles
Paul was one of the Beatles
George was one of the Beatles
Ringo was one of the Beatles
    for song in *.mp3
    do
        echo Copying the file $song
        cp $song ~/songs/
    done
    if (( age >= 21 && money > 4.00 ))
    then
        echo "You can buy a beer!"
    fi
    while [[ $suffix = "txt" ]]
    do
        somehow change the suffix
    done
    # Is this an executable file?
    if [[ -x index.txt ]]
    then
        echo index.txt is executable
    fi
    if [[ -r $filename ]]
    then
        echo $filename is readable
    fi
    if [[ -e $filename ]]
    then
        echo $filename exists
    fi
    if grep -q foobar $datafile
    then
        echo "$datafile contains the string \"foobar\""
    fi

Script                

Here is a small bash script. It changes file suffixes:                 

#! /bin/bash

old_suffix=$1
new_suffix=$2

for f in *.$old_suffix
do
    new_name=${f%.*}.$new_suffix
    echo Rename $f to $new_name
done

You might use it like this, to rename all of your C files (ending in .c) to be C++ files (ending in .cpp):                 

    chmod +x rn
    ./rn c cpp

The chmod command makes the script executable, so we can treat it as a program. You only need to do that once.                 

The leading ./ in ./rn means that we want to execute the file rn that’s in the current directory, not some other file named rn somewhere else.                 

Copy the script, above, to the file rn. No suffix—just the two-character filename rn with nothing after. You will modify rn, and turn it in for credit.                 

For this lab, you should:                 

  1. Understand how the script works. You don’t have to write any of these down, you just have to do them. All that you turn in is the file rn.
  2. Understand why we said ./rn as opposed to just rn.
  3. Copy & paste what I gave you into your own file rn, and try it out.
    Make sure that the first two characters in the script are #!, with nothing before them.
  4. Make it actually rename the file, rather than just saying so.
  5. Add a usage message if too many or too few arguments are given.
    A usage message is a message that tells the user what arguments to give to this script, if an improper number of arguments (including none) are given.
  6. Send the usage message to standard error.
  7. Complain (to standard error) if a file can’t be renamed.
  8. Not clobber existing files. That is, if we run the script like this:
        ./rn foo bar
and both alpha.foo and alpha.bar exist, the script should complain and refuse to do anything else.

For extra fame & glory (but no extra points), you could:                 

  1. Add a -n option that doesn’t rename, but just says what it would do
  2. Add a -v option that renames verbosely
  3. Complain if no files have the given suffix
  4. Make it work for filenames and suffixes that contain spaces
  5. Make it work for suffixes that are wildcards (whatever that means)

How to submit your work:                

In Canvas, check in the file rn to the assignment “Lab02”. It’s due 10:00:00ᴘᴍ MT Saturday, with a 24-hour late period for a 25% penalty.                 

How to receive negative points:                

Turn in someone else’s work.