Spring Semester 2005


Lecture Notes Three: Unix processes and process id's. File permissions. Introduction to Perl.

So your server is up and running?

How do you know?

Does this tell you anything?

burrowww.cs.indiana.edu% ps -ef | grep dgerman
 dgerman  8592  8589  0   Aug 28 ?        0:00 /u/dgerman/apache/apache_1.3.22/bin/httpd
 dgerman  8593  8589  0   Aug 28 ?        0:00 /u/dgerman/apache/apache_1.3.22/bin/httpd
 dgerman  8598  8589  0   Aug 28 ?        0:00 /u/dgerman/apache/apache_1.3.22/bin/httpd
 dgerman  8589     1  0   Aug 28 ?        0:00 /u/dgerman/apache/apache_1.3.22/bin/httpd
 dgerman  8596  8589  0   Aug 28 ?        0:00 /u/dgerman/apache/apache_1.3.22/bin/httpd
 dgerman  8591  8589  0   Aug 28 ?        0:00 /u/dgerman/apache/apache_1.3.22/bin/httpd
 dgerman  8590  8589  0   Aug 28 ?        0:00 /u/dgerman/apache/apache_1.3.22/bin/httpd
 dgerman  8597  8589  0   Aug 28 ?        0:00 /u/dgerman/apache/apache_1.3.22/bin/httpd
 dgerman  8594  8589  0   Aug 28 ?        0:00 /u/dgerman/apache/apache_1.3.22/bin/httpd
 dgerman 26850 26845  0 15:54:46 pts/23   0:00 -csh
 dgerman 26868 26850  0 15:54:58 pts/23   0:00 grep dgerman
burrowww.cs.indiana.edu% 
My server runs with a process id (pid) of 8589.

If I restart it, or stop and start it, it may get a new pid.

Can I find my server's process id anywhere else?

burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman
burrowww.cs.indiana.edu% cd apache
burrowww.cs.indiana.edu% cd apache*1.3.20*
burrowww.cs.indiana.edu% cd logs
burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/apache_1.3.22/logs
burrowww.cs.indiana.edu% ls -ld *
-rw-r--r--   1 dgerman  faculty     11465 Sep  4 15:42 access_log
-rw-r--r--   1 dgerman  faculty      1049 Sep  4 14:06 error_log
-rw-r--r--   1 dgerman  faculty         5 Aug 28 18:40 httpd.pid
burrowww.cs.indiana.edu% cat httpd.pid
8589
burrowww.cs.indiana.edu% 
A-ha!

Or something to that effect.

Let's stop the server.

burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/apache_1.3.22/logs
burrowww.cs.indiana.edu% kill -TERM 8589
Let's verify that it did go away.

burrowww.cs.indiana.edu% ps -ef | grep dgerman
 dgerman 27586 26850  0 16:04:04 pts/23   0:00 grep dgerman
 dgerman 26850 26845  0 15:54:46 pts/23   0:00 -csh
burrowww.cs.indiana.edu% 
What's grep?

What's |?

What is a pipe?

What does ps do?

What's Unix?

Let's restart the server.

burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/apache/apache_1.3.22/logs
Let's use a relative path to get to the apachectl utility.

burrowww.cs.indiana.edu% ../bin/apachectl start
../bin/apachectl start: httpd started
We're still in logs so we check that it really started.

burrowww.cs.indiana.edu% cat httpd.pid
28354
Let's restart the server by hand, and check the error_log file.

burrowww.cs.indiana.edu% kill -HUP `cat httpd.pid`
What happened? Does the server keep an eye on it?
burrowww.cs.indiana.edu% tail -3 error_log
[Tue Sep  4 16:09:02 2001] [notice] Apache/1.3.20 (Unix) configured -- resuming normal operations
[Tue Sep  4 16:09:22 2001] [notice] SIGHUP received.  Attempting to restart
[Tue Sep  4 16:09:23 2001] [notice] Apache/1.3.20 (Unix) configured -- resuming normal operations
burrowww.cs.indiana.edu% date
Tue Sep  4 16:09:39 EST 2001
burrowww.cs.indiana.edu% 
Have we used backquotes (`) before?

How does this work?

Now we have two questions:

Same thing.

Same difference.

Now we have another question:

Who will be there to start your server when the machines comes up?

You could have cron do it.

burrowww.cs.indiana.edu% crontab -l
crontab: can't open your crontab file.
At this point it's better to get our bearings.

burrowww.cs.indiana.edu% echo $EDITOR
pico
burrowww.cs.indiana.edu% grep EDITOR ~/.login
#setenv EDITOR emacs
# setenv EDITOR vi
setenv EDITOR pico 
burrowww.cs.indiana.edu%
Hmmm...

How do you source a file and why?

What's in .login and .cshrc?

What is Unix at IU?

burrowww.cs.indiana.edu% crontab -e
There's something that can't be shown here, but here's the result.

burrowww.cs.indiana.edu% crontab -l
0 * * * * /u/dgerman/apache/apache_1.3.22/bin/apachectl graceful
burrowww.cs.indiana.edu% date
Tue Sep  4 16:35:08 EST 2001
burrowww.cs.indiana.edu% 
What's cron and crontab?

Can you count to 8 in base 2?

Here's a table:

000   0
001   1
010   2
011   3
100   4
101   5
110   6
111   7
Knowing this would be enough.

Let's look at file permissions.

burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/public
burrowww.cs.indiana.edu% ls somefile
ls: somefile: No such file or directory
burrowww.cs.indiana.edu% touch somefile
burrowww.cs.indiana.edu% ls somefile
somefile
burrowww.cs.indiana.edu% ls -ld somefile
-rw-r--r--   1 dgerman  faculty         0 Sep  4 16:45 somefile
burrowww.cs.indiana.edu% chmod 345 somefile
burrowww.cs.indiana.edu% ls -ld somefile
--wxr--r-x   1 dgerman  faculty         0 Sep  4 16:45 somefile
burrowww.cs.indiana.edu% 
Did you follow that?

File permissions are a touchy subject.

Let's write programs in Perl now.

To write Perl programs you need to have the files executable.

Here now is a short, minimal introduction to Perl (to get us started).

Assume you read that. Let's now review it.

Perl is just a programming language. A variable in Perl is written like this:

$x
The name is x and the dollar sign indicates it's a scalar (has no dimension). A variable is just a location that is accessible by name. Not all data structures are that simple.

You can have lists, sequences of locations, indexed by their position in the sequence. If the name of the list is x then I can refer to the entire list as follows:

@x
The list could be empty or could have one or more elements in it. Let's say $i is a variable that stores an integer, then
$x[$i]
means the element with index $i in the list. Remember that the first element in the list has index 0 (zero) while the last element in the list @x can be accessed as $x[$#x].

We discuss assignment statements. The symbol for assignment is

=
and it splits the assignment into two parts.

  1. On the right hand side of the assignment we have expressions and values.
  2. On the left hand side we have locations.

So in the following assignment

$i = $i + 1;
the variable $i is used for its value on the right, and for its location (or address) on the right. (The result, of course, is that $i is incremented by one).

It's the same with elements of lists, since they're also variables. Their names are a bit more complex, since they are constructed from the name of the list and the index in the list and we need to use the brackets, but other than that they're names just as the names we're used to (the identifiers).

So, this assignment:

$x[$#x] = $x[$#x] + 1; 
will increment the value of the last element in the list @x by one.

Hash tables (or hashes, or association lists) are just like lists, but indices are not numbers, instead strings of characters are being used to index the values stored.

The indices must be unique and they are called keys.

To refer to a hash table as a whole we use

%x
and to get the individual elements we index using a $key.

If $key contains a string, and if %x is a hashtable then if there is anything associated with the value of $key in %x it can be retrieved or indicated with

$x{$key}
while, if there is no association we will either obtain an undefined value for it or obtain the ability to store one for this key, depending on where this expression appears with respect to the = (assignment operator).

Here's an example. Assume %x is empty to start with. Then

$x{"jordan"} = "bulls"; 
builds a first association.

$x{"miller"} = "pacers"; 
builds another, while
$x{"jordan"} = "wizards"; 
will change the value previously associated with jordan.

In general you can obtain the list of all keys in a hash table this way:

@theKeys = keys %x;
where %x is the hashtable.

Then you can use a foreach to go over all of them, for whatever processing purposes you may have in mind:

foreach $e (@theKeys) {
  $x{$e} = $x{$e} . " (nba)"; 
} 
The code above will add (nba) to each one of the values stored in the hashtable (since the . (dot) operator is used for concatenation in Perl). So if you print $x{"miller"} now it would read pacers (nba). That's the first part of the Perl review we need.

In lab this week you will implement a simple CGI script.

You will develop it in stages.

We place a minimal script (called hello) in cgi-bin.

Here's the code in it.

#!/usr/bin/perl
        
print qq{Content-type: text/html\n\n<html>
  <head>
  <title>
  the hello script
  </title>
  </head>
  <body bgcolor=white>
  <h1>Hello!</h1> 
  <img src="http://www.cs.indiana.edu/dept/img/lh08.gif">
  </body>
  </html>
};
Its output is the same as when we access the hello.html file on the web.

The difference between them is that the script is entirely responsible for the output and so it has to start it with its MIME type (followed by an empty line). Thus,
"Content-type: text/html\n\n"
is the first thing that the script is supposed to write.

Note the two newline characters: An empty line is required after the MIME type.

We now take the script and change the output a little, to make it display an image. (That's what the lab is about, and the following is a birdeye's view of all the steps in the lab this week).

So we then think whether we could make it display something new every time. And we introduce a bit of randomness in it, such that the output is changed from time to time. This way most of the times, most likely, the output changes.

To implement the change in output we create a list of names of images. Then every time the script is called a random number that represents an index in the list of names of images will be produced and the image with that index will appear in the output.

That's an improvement, the output is changing, but it's not that predictable. Is there any way to make the user participate, and maybe choose the output? Can the user then talk to the script (instead of just starting it?). The answer to all these questions' yes, but I'm sure we won't have time for that today. So we'll see you in lab.


Last updated: Jan 20, 2005 by Adrian German for A348/A548