User Tools

Site Tools


haas:spring2010:scripting_fun

Basic Shell Scripting Fun

Today in class while exploring wildcards, we found our way into the realm of shell scripting. This realm, a powerful if not initially mystical place, is a source of great power that can truly be a stepping stone to significant UNIX enlightenment.

In the beginning

We started with the basics of how to start a shell script, using the decisive “shabang”:

#!/bin/bash

Comments: Remembering then what you do now

As stated, things like comments are initiated with a “#” and are good from that point to the end of the current line.

And remember, the FDA recommends 5 servings of comments a day for a proper balanced diet.

Output: Singing your song to the world

Like many of the puzzles and quests you've encountered in UNIX thus far, you should hopefully be well aware that there are many solutions to any given problem. With that said, there is also plenty of ways to output something.

For now, the common basic output statement is that of: echo

echo is a built-in command to bash, that will display whatever string you pass to it. It is rather simple, having two common usages:

    # Example 1: Output with newline
    echo "Hello, World!"
 
    # Example 2: Output without newline
    echo -n "Enter a value: "

In the case of the 2nd example, eliminating the newline will basically prevent the output from moving the cursor to the next line, so you can allow for more intuitive interactions with the user running the script.

Input: Letting the user talk to you

To obtain input, we would use the “read” command, followed by a variable:

    # Obtain input and store it in a variable called "stuff"
    read stuff

Bash Variables 101

Variables in scripting languages are often simpler to utilize. Instead of worrying about declaring and determining their storage type and range/sign details, we just USE them when we need them.

Also of importance, when ASSIGNING a value to a variable (through input or direct assignment), we reference the variable merely by name. When we want to expand it and access its contents, we prefix the variable with a $ sign, which the shell uses as a “variable expansion” operator.

For example:

    # Get input from the user, then output the input
    read value
    echo "You just entered $value"
 
    # Directly assign some values, then print them out
    myvar=12
    stuff="more stuff"
    echo "$stuff is $myvar"

Variable input as command output: Command expansion

A very powerful feature present in bash shell scripting (and many other UNIX shell scripting environments) is that of command expansion, initiated with the use of the backquotes (` symbol, on the ~ key below ESC), you basically can insert something you could type on the command line, and the output of that will be what is actually substituted in place of the quoted string.

For example:

    # Nicely display how many groups you are in
    echo "You are a member of `groups | wc -w` groups"
 
    # You can also assign that to a variable
    groupnum=`groups | wc -w`
    echo "You are a member of $groupnum groups"

Decisions, decisions...

Scripting has many of the regular programming constructs available for use.

We'll start with the venerable if statement:

    # prompt and input a value, assume it is numeric, and display a message based on its value compared to 50
    echo -n "Enter a number between 0 and 100: "
    read number
 
    if [ $number -lt 50 ]; then
        echo "$number is less than 50"
    elif [ $number -gt 50 ]; then
        echo "$number is greater than 50"
    else
        echo "$number is 50"
    fi

if statements begin with the familiar “if” keyword, and in this example make use of the “[” and “]” commands– yes, “[” and “]” are COMMANDS… they exist in /usr/bin, and have a manual page (be sure to check it out). if statements are followed by a “then” keyword; if you have an “else if” statement, it is represented as “elif”, and for else it remains simply “else”.

A key difference in bash's if statements is that they MUST be terminated by the ending “fi” keyword (which is simply “if” spelled backwards).

In this example, relational operators are represented as “-lt” for numeric less than, “-gt” for numeric greater than.. and the other common variants are available (check the bash manual page).

This is one of those instances where we make a distinction in the format of a variable's data… by default, it is pretty much treated as a string. But if we want it to be an integer, we just make sure to treat it as such when we want it to be that way.

Relational operators like “=”, “<”, “>” and company are treated as string comparisons. (Rumor has it that recent versions of bash blur this distinction, and you can actually get away with the familiar operators for both– but be mindful that if you do this and try to run your script on a sufficiently old version of bash, your script may crash and burn).

Things like input validation we'll endeavor to cover later, as a more advanced exercise.

Rehearsing your play

A script is in some ways like a play, put on by eager thespians.

That said, it is important to ensure your script does not have any errors in it. Pretty much any element in your script can be manually typed out on the command-line for manual testing.. so don't be afraid to specifically test certain situations to make sure they make sense to you before blindly just adding them to your script wondering what may happen later.

Performing

When you are ready to see your script in action, save and exit from your file.

We must make our script executable, and we can do this merely by adding the “x” permission to the user field using the chmod command. NOTE that you do NOT need to “compile” your script.

Once your script is executable, run it by providing a relative path.

For example, let's say we have a script called “myscript.sh”…

lab46:~$ chmod u+x myscript.sh
lab46:~$ ./myscript.sh

And you will be interacting with your script.

Questful Challenges

This week, I would like for you to write some scripts that do the following:

  • Prompts the user for their name, stores it in a variable, and outputs that name along with its length in units of characters.
  • Obtain 4 numbers from the user; in a variable called sum, store the sum of these 4 numbers. In a variable called product, store the product. Consider utilizing “bc” to assist you.
  • Prompt the user for some text, store it in a variable. Convert any uppercase letters to lowercase and store that in a separate variable. Display the before and after.
  • Write a “guess the number” game that allows the user 4 chances to guess the number.
  • Write a script that counts how many times you've logged in this month.
  • Create two or three sample text files, and write a script that simulates a database-y operation (like SELECT, VIEW, or JOIN– not all, just pick one and do it, commenting on what that operation should do, and how you've accomplished it)
  • Write a script that, when run, will download a web page and compare it to an existing, but older, copy of the webpage and displays any differences OR performs a line/word count; then rename the current copy to a backup, and remove the old backup in preparation for the next run- you might want to do this on some web page whose HTML output might change somewhat regularly (digg, slashdot, google news, etc.)
  • Devise and implement a simple script of your own whose purpose is well-defined, and implementation well-documented.

Put your final scripts on your week 6 journal entry inside dokuwiki file tags, as follows:

<file bash myscript.sh>
#!/bin/bash
#
# myscript...
#
echo "blah"
read var

do stuff
exit
</file>

this will apply bash-style syntax coloring, and also provide downloadable links. Make sure to have all 8 of the requested scripts present in separate downloadable links on your journal page.

Be sure to ask questions. Questions are the only way you will effectively approach the answers and knowledge you seek.

haas/spring2010/scripting_fun.txt · Last modified: 2013/12/22 17:43 by 127.0.0.1