Tuesday, December 6, 2011

Finishing Projects

For projects 8 and 9, we need to get input for 6 employees and return a formatted list for a payroll sheet.

                In pseudo code (not actual code), this goes something like:
            Create a temp file containing the headings (number, name, rate, hours, etc)
                (echo "Number Name Rate...etc" > temp)
            Create a total variable to store overall total pay for all employees
            While loop for 6 passes
                read number name rate hours overtime
                regularpay=rate*hours
                overtimepay=rate*overtime
                totalweeklypay=regularpay+overtimepay
                total=total+totalweeklypay
                store variables as a new line in temp file
                    (number name rate hours overtime regularpay overtimepay totalweeklypay >> temp)
            done with while loop
            echo “Weekly Payroll”
            use awk to format each line from the temp file                                awk '{printf "%-6s%-13s%-10s%5s%8s%10s%9s%8s%8s\n", $1, $2, $3,"$"$4, $5, "$"$6, "$"$7, "$"$8, “$”9}'        (you may need to edit the %numbers)
            echo “Total: \$$total”

Also, to make this work for reading from a file for project A, try adding “< $1” after the “done” in the while loop.  This takes the first parameter passed at the command line and uses it as the file entry for the read command.

That gets you through project B, actually, since the AWK command is all that’s needed to complete it.  As for “discount”, that’s a new script, and can be found entirely in the student manual, under page 34 or 35 I believe.

Good luck, acolytes!

Monday, December 5, 2011

Ways with Arrays

A collection of variables can be stored within one variable using an array.  It's fairly straghtforward; simply call like a variable like normal, but add a number after it with [] brackets, like this: variable[1]

This one's going to be a hefty example, so bear with me.

#!/bin/bash
#
#Array Demo
#By Jason Groce
#Created 12/5/2011
#
#An Array is a variable that contains multiple values.
#Each value is numbered after the name of the array,
#such as array[4], which may be used as a standard
#variable with special notation, such as $(array[12])
#

echo "This is a demo of how an Array functions."
echo -ne "You may pass a file name to populate the array "

echo "or enter variables manually."
echo -ne "(The file should contain names and numbers,"

echo "one of each per line.)"
echo

typeset -a names
typeset -a numbers
typeset -i num=0

if [ ! -f $1 ]||[ ! $# -eq 1 ]    #if no filename entered
then
        echo -ne "You did not enter a valid file name; "

        echo "begin manual entry."

        echo "Please enter 10 Names, one per line: "
        num=0
        while [ $num -lt 10 ]  #10 times, save name to record
        do
                read names[$num]
                num=$num+1
        done

        echo "Please enter 10 Numbers, one per line: "
        num=0
        while [ $num -lt 10 ]  #10 times, save number to record
        do
                read numbers[$num]
                num=$num+1
        done

else            #if a valid file name entered as parameter
        echo "You entered file $1"

        num=0
        echo "Populating arrays..."
        while read name number  #record name/number for each line
        do
                names[$num]=$name
                numbers[$num]=$number
                num=$num+1
        done < $1
fi

num=$num-1
typeset -i record=0
while [ ! $record -eq 99 ]
do
        echo -ne "Enter a number 0 to $num to display a record "

             "or '99' to quit: "
        read record
        case $record in
                99) echo "Quit"
                     exit
                     ;;
                *)  typeset -i recordNum=$record
                    echo -ne "Record $record "

                    echo -ne "${names[$recordNum]} "
                    echo "${numbers[$record]}"
        esac
done



This script can be coupled with a file containing names and numbers/values, such as this:

Paul pbille
Jason f52560
Richard f49150
Jonathan f51970


To try this out, creating the script as "arrays.sh" and the file as "arraydata.dat", run the command like this:

./arrays.sh arradata.dat

To summarize this, you create an array with typeset -a variable, add data to each array value like this, variable[5]="data", and access that data like this, ${variable[5]}.

Questions? Enjoy, weenix's!

Wednesday, November 30, 2011

Passing the Parameters, Please!

When entering a command to run a shell, you can actually tell the program information on
the same line.  These parameters can be used within the script as variables.  For
example:

$> ./program.sh Jason 50 75

This tells the program to use Jason as the first parameter, 50 as the second, and 75 as
the third.  In program.sh, we can access the parameters like this:

echo "Name: $1"
echo "One: $2"
echo "Two: $3"

The $ sign followed by a number is special in unix scripting to use parameters.  The
code above would produce this:

Name: Jason
One: 50
Two: 75

The parameters can also be file names if you like.  Now you can enter quick custom
commands in one line.  Enjoy, technophiliacs!

Working them Files

Files can be read and written to in a number of ways in Unix, and shell programming
takes huge advantage of this.  Firstly, let's look at the basic input-output of a file.

$> echo "Write this to a file" > file.txt
$> echo "Write this, too!" >> file.txt
$> cat file.txt
write this to a file
write this, too!
$> echo "Overwrite the file with this!" > file.txt
$> cat file.txt
Overwrite the file with this!

As you can see, the > command tells the echo command to write the first line to
file.txt, and the >> command tells echo to add the words as a new line in the file. 
Each time we use the > command, it overwrites the entire file, replacing the contents.  
The >> simply adds new content as a new line to the end.

Not to sound too redundant, but let's try this in a loop:

while read line                #loop this while there is
                               #still a line to read
do                             #start the loop
                echo $line     #say the contents of the line
done < file.txt                #use this file.txt as the input

This crazy looking thing is best read almost backwards.  The file, called file.txt, is
input on the done line, one line of the file at a time.  When the while command tries to
read the file, it sees only one line of the file each time through the loop until there
are no more new lines.

Now let's imagine we have a file called example.txt that looks like this:

Jason 50 75
Groce 100 299

You can also store the name of the file in a variable and use the variable in place of
the file name after the < symbol.  Using the following while loop, we can manipulate
this a bit more.

filename="example.txt"                  #make a variable
                                                       
while read name num1 num2               #use the line from the
                                        #file to read variables
do                                      #start the loop
                echo "Name: $name"      #say the name
                echo "One: $num1"       #say the first number
                echo "Two: $num2"       #say the second number
done < filename                         #use example.txt to
                                        #input lines of variables

The output would look something like this:

Name: Jason
One: 50
Two: 75
Name: Groce
One: 100
Two: 299

Code away, techies!

While-Do Loopy and Case-Esac Overstatements

By now, I hope everyone know if-then statements.  Just in case, here's a super quick
example:

if [ $num -eq 5 ]
then
                echo "The number is 5!"
fi

If something is true, then do this, and end the command with "fi".  While-do loops and
case-esac statements aren't much different.  A quick example for while:

typeset -i num=0               #create an integer,
                               #not always used for while,
                               #just an example

while [ $num -lt 5 ]           #keep doing this while
                               #num is less than 5
do                             #start loop
                echo "$num"    #say the number num
                num=$num+1     #add 1 to number
done                           #done with this loop

By adding other commands, the while loop can get to look very complicated, but the basic
archetecture is the same each time.  Now for an example case-esac:

read input                           #read input from the user,
                                     #again just an example

case $input in                       #use the variable $input
                1) echo "one";;      #if input is "1", say "one"
                2) echo "two";;      #if input is "2", say "two"
                a) echo "AAA";;      #if input is "a", say "AAA"
                hello) echo "hi";;   #if "hello", say "hi"
                q) echo "goodbye;;   #if "q", say "goodbye"
                *) echo "huh?";;     #if anything different
                                     #than above, say "huh?"
esac                                 #done with case statement

I hope this helps.  Until next time, codemonkeys!

Tuesday, November 15, 2011

Programming in Unix 101

Let's go over a few programming basics, as we haven't gotten a proper review of them in class just yet. A program contains variables, parameters and arguments that can be acted upon by commands. For example:

Command Parameter Argument
ls -l name

This would return a list of files in long format containing the word name in the title. The argument, in this instance "name", can also be replaced by a variable, which would be represented by a $ followed by the variable name, such as $NAME.

A variable is merely a container for something, such as a string (ie, a word) or an integer (a number). Strings cannot be added, subtracted, etc, but integers can. (Note: an integer is a whole number, without a decimal point.) To create a string variable, simply decide on a name and tell it to store something.

NAME="Jason"

However, to create an integer variable, it needs be made into the type integer. This command should work better:

typeset -i AGE=28

These can be handy, but don't do much sitting out in the open without a script file. Creating a script file is as easy as making a file executable and editing the contents with an editor like vi. The easiest way to create a file to edit with vi is like this:

vi filename

Make sure you're in the directory you want to create the file in, or
specify the directory you want to use when typing the command (vi
folder/filename). Now inside vi, it's time to create a script. (In vi,
press i to use input mode, and escape to enter command mode.) It's a
good idea to start the script with this:

#!/bin/bash

The # indicates a comment, and will not run a command, but this special
line also tells the shell to run this in the bash or Bourne Again Shell,
so that any commands used in the script will work like normal to the
shell used in class. The next few lines should contain some information
about the file for future editing purposes:

#
#Script by Jason Groce
#This is an example script
#Created 11/15/2011
#Last Edited 11/15/2011
#

Now let's get to programming. We need a function for this script to
accomplish. How about finding out how old you are in seconds? For
this, we need to ask the user some information and act upon that
information. Let's get the name and birthdate for the user first:

echo
echo "What is your name? "
read yourname
echo ""
echo "What is your birthdate? (yyyymmdd)"
read bday
echo ""

Now it's time for some crazy math fun (okay, this is a bit out there, sorry):

#Seconds elapsed
typeset -i seconds=$(date +%s)-$(date -d $bday +%s)

Fairly precise, this subtracts the length of time between the creation of Unix and the $bday variable from now. And finally, to display the output of the script:

echo "Hello, $yourname, you are $seconds seconds old!"

There we have it! Save the file (in vi, use shift+Z+Z to save and close or :w filename to save as a new file), and run the script:

[f52560@bearybear ~]$ ./filename

What is your name?
Jason Groce

What is your birthdate? (yyyymmdd)
19830221

Hello, Jason Groce, you are 906751610 seconds old!

The reason for the ./ is because the $PATH variable used to identify the default location of programs does not include the path to the script just created. (Remember figlet?)

Enjoy, script-kiddies!

Tuesday, November 8, 2011

More links:

Class website, for at home access:
https://linuxsandbox.coleman.edu/~pbille/com259/index.html

Scripting

A tutorial on scripting, with some examples:
http://www.dartmouth.edu/~rc/classes/ksh/

Another tutorial site, similar in flavor to the last:
http://steve-parker.org/sh/sh.shtml

Compression

A short description of compression:
http://www.devdaily.com/unix/edu/examples/compress.shtml

And a longer description of compression:
http://www.kingcomputerservices.com/unix_101/compressing_files_in_unix.htm

Utilities

A list of Unix utilities‏, most of the links don't work, but you can find these in my first post in the links to command listings:
http://parallel.vub.ac.be/documentation/linux/unixdoc_download/Utilities.html


And a bit of THOROUGH info for some commands:
http://www.people.fas.harvard.edu/~lipoff/miscellaneous/unix.html

Goodnight, nerdlings!

-Jason

Messaging in Unix

First, you need to know who to message.  To get a list of online users, you could type:

~ : who
f52560   pts/26       2011-11-08 19:00 (10.10.30.116)
f66420   pts/28       2011-11-08 19:22 (10.10.30.107)
f51970   pts/31       2011-11-08 19:16 (10.10.30.104)
f57980   pts/32       2011-11-08 18:03 (10.10.30.105)
pbille   pts/36       2011-11-08 14:34 (10.10.30.170)
f49150   pts/37       2011-11-08 18:07 (10.10.30.102)
f56340   pts/42       2011-11-08 19:21 (10.10.30.101)
pbille   pts/44       2011-11-08 19:22 (10.10.30.170)
f57870   pts/40       2011-11-08 19:25 (10.10.30.110)
f53490   pts/45       2011-11-08 19:22 (10.10.30.106)
f55930   pts/46       2011-11-08 19:23 (10.10.30.108)
f57710   pts/47       2011-11-08 19:23 (10.10.30.112)
f56600   pts/49       2011-11-08 19:27 (10.10.30.111)
f56340   pts/50       2011-11-08 19:24 (10.10.30.101)
f54110   pts/51       2011-11-08 19:27 (10.10.30.113)


But the list you get, while it has usernames, doesn't have real names, and is not really useful if the username is something like f52560.  So, let's try this:

~ : finger
Login     Name               Tty      Idle  Login Time   Office     Office Phone
f49150    RICHARD LUJAN      pts/37         Nov  8 18:07 (10.10.30.102)
f51970    JONATHAN TAN       pts/31         Nov  8 19:16 (10.10.30.104)
f52560    JASON GROCE        pts/26         Nov  8 19:00 (10.10.30.116)
f53490    MARK TELLES        pts/45         Nov  8 19:22 (10.10.30.106)
f54110    NICHOL GOLSTON     pts/51         Nov  8 19:27 (10.10.30.113)
f55930    ALEXAND NIMLEY     pts/46         Nov  8 19:23 (10.10.30.108)
f56340    JUST RODRIGUEZ     pts/42      4  Nov  8 19:21 (10.10.30.101)
f56340    JUST RODRIGUEZ     pts/50         Nov  8 19:24 (10.10.30.101)
f56600    DAVI MCPHERSON     pts/49         Nov  8 19:27 (10.10.30.111)
f57710    DAVID SILVA        pts/47         Nov  8 19:23 (10.10.30.112)
f57870    GASP HERNANDEZ     pts/40         Nov  8 19:25 (10.10.30.110)
f57980    ANGEL M ANGULO     pts/32         Nov  8 18:03 (10.10.30.105)
f66420    Michael Respicio   pts/28         Nov  8 19:22 (10.10.30.107)
pbille    Paul Bille         pts/36   4:36  Nov  8 14:34 (10.10.30.170)
pbille    Paul Bille         pts/44         Nov  8 19:22 (10.10.30.170)
pbille    Paul Bille         pts/52         Nov  8 19:27 (10.10.30.170)


Now we get usernames and the actual name.  With this, we can try something like:

~ : write f52560
write a message here
(CTRL + D)


This will send a message to the specific user.  You can only send a message to one user at a time, and can send multiple lines of text.  Pressing the CONTROL key and the D key at the same time exits the message and brings you back to the command entry mode.

Now, for the fun one.  Broadcasting a message, so that EVERYONE on the server receives it.  Be careful, because this means EVERYONE!

~ : wall
This is a message to EVERYONE!
(CTRL + D)


Enjoy your firecrackers, kiddles!  Don't put out an eye!

-Jason

Review Time!

I found a few articles that may be useful.  First up is "Learn UNIX in 10 minutes."  It seems pretty decent, and goes over pretty much everything we have learned so far:

http://freeengineer.org/learnUNIXin10minutes.html

Next up, here's a tutorial for beginners, with lesson plans and screen shots.  Not much beyond what we've learned so far, but good for review:

http://www.ee.surrey.ac.uk/Teaching/Unix/

From that site, we find a link to recommended books.  From what I've found, these are the best ones out there, and are recommended on many Unix sites and forums:

http://www.ee.surrey.ac.uk/Teaching/Unix/books-uk.html

Now for another rare find: a free book on Unix from 1993, "Unix is a four letter word."  It's an interesting read, covers a pretty thorough history of Unix and commands, and has a touch of geek humor.  Okay, so it's 18 years old, and dates back before the Internet, but I find it valuable enough to read it, so maybe you will, too:

http://unix.t-a-y-l-o-r.com/index.html

See you at the midterm!

-Jason

EOF

Monday, November 7, 2011

Unix notes, for a better tomorrow.


I get the feeling that most of us in the Unix class aren't taking much away from the lessons.  Maybe it's time to take the learning into our own hands, and maybe we'll get further than the 2-steps forward and 1-step back approach we've encountered thus far.

First, let's drop the physical book and find a digital copy, for free.  A simple Google search for the ISBN of the book, and here's a great link:


It's 6.7 Mb, so don't expect the school network to make it an easy download; I suggest you get it at home if you need/want it.

Now for a decent command listing:


Just in case you are feeling a bit masochistic, I also found a free book about Unix text processing from 1988.  It's old, references things like dot-matrix printers, and has a lot of extraneous information, but it is useful in learning some vi commands and interesting Unix things.  Also useful if you need a nap:


So, we've got the text, the reference card, and extra material.  Now, what about a place to practice?  Well, imagine this: an online terminal to try out, without needing to install anything special?

http://sdf.lonestar.org/ (click on "ssh" at the top right of the screen; requires Java)

Now maybe, just maybe, we have a viable environment to learn something on our time.  Good luck, luddites.  ;)

-Jason