We mentioned earlier that Unix has a kernel layer that "talks" to the hardware and a shell layer that acts as an intermediary between the user and the kernel. There are at least three different Unix shells that are used. The one that you get by default when you use a Unix system is determined by the installation. Here we will look at the "C shell" which is the default within the Computer Science Department at SJSU.
Metacharacters are sometimes called "wildcard" characters. Metacharacters are recognized by the shell. These characters can allow you to specify a group of files at one time, for example. When used with certain Unix commands, they allow you to select just the files to which you want to apply the command without having to re-issue the command over and over on each individual file.
Create a subdirectory under your home directory in which you will place certain files for this module. Go to that directory and issue the command:
cp
/handouts/cs46blab/* .
We have already seen that the '.' character stands for
"this directory". The first part of the copy command is a
filename but the '*
' character is not part of the
filename.
Instead, this is a metacharacter. We'll see more about metacharacters in the context of regular expressions in another module. When used as part of a filename, Unix takes the character to mean that any string of characters (zero or more) will match that character. In particular, since every filename in the directory from which you are copying files has a name consisting of characters, you will match every filename in that directory. That is, you will copy every file from that directory to your working directory. Check this by listing the files in your working directory.
In order to further examine the use of the '*
'
metacharacter, type the following command from your working directory
containing the files you just copied:
ls
-l *.txt
What do you see? Which files got left out of the listing?
Issue an ls
command that will display the long
listing for just the files with the characters "list"
somewhere in the filename (hint: you can use '*
' in more
than one location).
The '?
' is another metacharacter. The shell will try to
match a single character in place of the metacharacter. For
example, type:
ls
-l Chap?.*
You can also use the "[...]
" as
metacharacters. The shell will match any single character within the
square brackets. For example, type:
ls
-l Chap[12].txt
Notice that there are no blanks or commas between the characters
to be matched. How would you get a long listing for Chap2.txt
and Chap3.txt
but not Chap1.txt
?
Suppose you wish to transfer to subdirectory "sub1
"
just under your home directory from a subdirectory deep in the tree
hierarchy under your home directory. One choice is to issue the cd
command with no parameters which will place you in your home
directory and then to issue the command to take you to the sub1
subdirectory as in:
cd
cd
sub1
An alternate choice is to use the '~
' metacharacter
by typing:
cd
~/sub1
The '~
' metacharacter is interpreted by the shell to
mean your home directory.
Although we have exhibited the use of metacharacters with just a
few Unix commands, they can be used with many of the commands. For
example, they can be used with the rm
command. One should be careful with the use of metacharacters. For
example, if you typed rm *
you would delete all the
files in the directory in which you were located. This might be what
you want to do but beware!
One good piece of advice is to check which files you will
actually affect with the use of metacharacters by using the same
characters with the ls
command.
The C shell has a feature that allows you to customize your computing environment by allowing you to rename or abbreviate the standard Unix commands.
Type the following command:
alias
ls ls -l
and then follow it with the command:
ls
.
Even though you did not use the -l
option you still
got the long listing. This is because the alias
command
set up an alias between the ls
command and the ls
command with the -l
option. Think of it as the
following: each time you enter ls
as the command name,
the shell will substitute the replacement text that you supplied in
the alias
command.
One very useful alias is the following:
alias
rm rm -i
What is the -i
option? (Use the man
command to find out.) How will this be useful? Actually, you may
already have this alias installed as a default on the system you are
using. We'll see shortly how this is done.
Go to your home directory. If you issue the ls
command with the -a
option, you will see that there are
a number of files that you normally don't see. Each of these files
begins with the '.' character. These files are usually
resource files that are used by various programs in the Unix
environment.
One of these files is .cshrc
and is the resource file
read by the C shell when it first starts up. The file is just a text
file and you can modify it to fit your needs. One of the ways you can
use this file is place any aliases you wish to use all the time.
Aliases that you enter on the command line as we did above will
disappear when you logout from the system.
Here are some aliases you may wish to add to your .cshrc
file. To add them, use your favorite editor to edit the .cshrc
file. Place all the aliases together so that you can quickly locate
them if you want to make changes. You probably already have a few
there as a result of the default .cshrc
file that you
were given with your Unix account.
alias ls ls -F
The -F
option will
tell ls to place the '/
' character after the names of
any directories. This allows you to quickly distinguish between
directories and files.
alias dir ls
Old habits die hard. If you are a
DOS user who can't remember to use ls
to view your
directory, you can alias dir
to the ls
command. By the way, if you have already aliased the ls
command to ls -F
as above, then dir
will
also produce the same result as typing ls -F
.
alias bye logout
You can probably come up with
lots of these that customize your interaction with the Unix C shell.
It's probably best to restrict yourself to a few of these aliases.
Otherwise you may find yourself on a Unix system someday that doesn't
support aliases and you won't remember any of the (un-aliased) Unix
commands. Not all shells allow this feature.
alias cd 'cd \!* ; ls -F'
This one takes some
explanation. The single quote character surrounding the string that
is to replace cd
is there to "protect" it from
the shell. The '*
' character is a metacharacter and the
shell would ordinarily try to treat it in that way while it was
executing the alias
command. Instead, we want the
metacharacter to be handled later after the cd
string has been replace by the characters between the two single
quote characters. The '\
' character together with the
'!
' and the '*
' characters will cause the
parameters that you supply to the cd
command (after it
has been aliased) to be copied into this spot. The ';
'
character serves as a separator between Unix commands, allowing you
to have two or more commands on a single line.
In the end, what you will have is that every time you issue the cd
command, you will also get the ls -F
command being
issued to show you the files and directories in the directory to
which you have changed.
Once you have entered the aliases
into your .cshrc
file, they will be available to you the
next time you login. You can tell the C shell to read them now and
make them available to you now by telling it to read the .cshrc
file with the command:
source
.cshrc
Once you have issued the source
command, your aliases
are now available to use immediately.
One of the other features of the C shell is something called history. At the command line type:
history
You should see a number of lines printed on your screen. They will be the previous commands that you entered.
The default number is 20 here in our department but that number
can be reset to whatever you wish. (The number can be reset by
inserting the following line into your .cshrc
file set
history=nn
where nn is the number you wish.)
Having the ability to view past commands is of some interest but
the nice feature is the ability to re-issue commands without having
to retype them. Here is an example of what one might see after typing
the history
command.
41 14:31 dir 42 14:39 grep alias .cshrc 43 14:58 history 44 14:58 grep history .cshrc 45 15:00 cd projectFolder 46 15:00 cd patternFolder 47 15:01 cp PatternMaker.java PatternMaker.java.save 48 15:01 vi PatternMaker.java 49 15:02 javac -deprecation PatternMaker.java 50 15:02 vi PatternMaker.java 51 15:03 javac -deprecation PatternMaker.java 52 15:03 java PatternMaker 126 10000 53 15:03 ps 54 15:04 kill 3821 55 15:04 ps 56 15:05 rm PatternMaker.java.save 57 16:57 cd 58 16:58 grep history .cshrc 59 17:01 history 60 17:01 history > temp
The shell keeps a counter for the commands you have entered since you logged into the system. In this case the last command that was typed was the 60th since logging on. The most recent 20 commands are shown. The second column shows the time of day when the command was issued. The remaining information on each line is the actual command that was executed.
Use the results from the history command you typed earlier. Here we will refer to the history record shown above but yours will, of course, be different. Type the following command (instead of the number 58, use an appropriate number for your history record):
!58
What do you see? What has happened?
Issue three different ls
commands. For example, you
could issue some of the ls
commands used earlier in the
exercise using metacharacters.
Now type the command:
!ls
What do you see? Which of the previous ls
commands
was issued?
The character '!
' tells the C shell to search the
history record working backward from the most recent command.
If you specify a number, then it will execute that command. If you
specify a character string following the '!
' character,
then it will look for a command that begins with those characters. If
we look at command number 49 above, we can see that if we were making
some changes to the source file and then re-compiling, that it would
be easier to type:
!49
or
!javac
rather than having to re-type the entire command.
You have to be aware that the shell's history mechanism merely
re-issues the command that you had issued earlier. It may not make
sense to re-issue that command if things have changed. For example,
if you re-issue a javac
command but are no longer in the
directory containing the source file, then javac
will
report that it could not find the source file.
Unix is a multitasking operating system. This means that that it can have multiple tasks running simultaneously. A Unix task is usually called a process. There is also a special type of Unix process called a thread, which you will study in advanced coursework. In this lab, we will identify a task with a process. You have been running at least two processes at different times in this lab. One is associated with the window in which you are viewing this "lab manual". That process is running Netscape or some other browser. Another is any Unix command that you run in a separate window.
Actually, since there is probably only one central processing unit in the machine you are using (some Unix machines, like the file server in DH450, have multiple CPUs each capable of running separate processes simultaneously), there can really only be one process running at a time. Unix is capable of switching between processes quickly. If you are browsing the network, for example, then in the time that it takes a file to download from some other site on the network, you can go back to the window in which you issue Unix commands and ask for a listing or directory change. The browser task is still being given time as it needs it and the Unix command is being carried out as Unix rapidly switches between the two tasks.
The situation is even more complicated on the Sun workstations in the department since Unix is also a multi-user operating system. It can handle multiple users at the same time. Actually, this is just an extension of the multitasking concept.
ps
This is the process status command. You will see displayed on the screen a table containing 5 columns. Each line in the table corresponds to a process that Unix is running on your behalf. Some of these may be related to the windows environment, some of these may be related to the process you have running the browser, etc. The PID column is the process ID for each process. This is a number assigned by the Unix system that uniquely identifies the process.
The TT and STAT columns have to do with the terminal to which the process is attached and the status of the process (e.g. IW = idle and waiting).
The TIME column gives you the amount of CPU time that has been consumed by that process so far and the COMMAND column gives you the command itself that is being executed by that process (e.g. -csh = C shell process).
Unix has the ability to run a
process in a "background" mode. This means you can issue a
command and gain access to the terminal immediately so you can issue
another command. This is useful if you have some process that is
going to take a long time and you want to work on something else
while Unix executes the command. All you have to do is place the '&
'
character at the end of the command.
Copy the file Patterns.java
and PatternMaker.java
from
/handouts/cs46blab
(if you don't already have
a copy from an earlier module). Now type the command:
javac Patterns.java
followed by:
java Patterns 126 10000 > temp &
Now immediately type the command:
ps
How can you tell if java
was operating in the
background? What message, if any, did you get to tell you that the
java
task was completed?
There is a way of placing an active process into the background and suspending it. This will halt its execution temporarily but won't kill the task.
Remove the file named temp that you created in the previous exercise. Then issue the command:
java Patterns 126 100000 > temp
Now type:
^Z
(That's an upper case Z
while you hold down the
control key.) What do you see? Check out if the process is still in
the system using ps
. What do you see? Has the java
process
accumulated any CPU time? How much? Wait a few more seconds and type
ps
again. Does it appear that the java
process is executing in the background?
fg
This puts the process that you formerly suspended into the
foreground. After a few more seconds, suspend the
process again (how?) and use ps
to have a look to see
what is happening. Has forever accumulated any more time? How much
more?
Suspend the java process again (if it has completed then remove the temp file and start it again first).
Issue the ps command again and note the PID number (Process ID) for the java process. What is the PID for the java process?
Now we want to simply kill the process before it takes up any more CPU time. To do this type (instead of 4333, use the correct PID for your process):
kill
4333
Now use ps to see if the java process is still active. What message do you see to indicate otherwise?
Sometimes using kill
is the only way to get out of a
process that is stuck in an infinite loop.
Click on to go back to the main directory.
Click on to take the quiz for this module.
These pages were developed by John Avila SJSU CS Dept.