aace - Jan Newmarch

advertisement
Teaching Shell Programming in a GUI Environment
First Author
Affiliation, Country
Email Address
Abstract: Scripting and command languages are important programming paradigms that many
computing students need to learn. However, they are usually presented in a terminal-based
environment, which is foreign to students used to a windows GUI environment. This paper
discusses “scriptlets” - small windows applications that are designed to be used in shell scripts. It
shows how these can be used to teach shell programming constructs, while giving a GUI flavour to
the lessons. Student reaction is also discussed..
Scripting and command languages
Students in technically-oriented computing courses such as Computer Science or Software Engineering need to learn
a variety of programming languages and language paradigms. Two of the major paradigms are those of scripting and
command languages, and one of the Unix shells (typically the Bourne shell) is often used for this. (It must be noted
that there are no generally accepted definitions of either scripting or command languages, or the
differences/similarities between them. What follows is the author's viewpoint, with carefully selected references.)
Scripting languages introduce students to the ideas of weakly typed languages, where the programs are often
substantially shorter than a corresponding program in a strongly-typed language (Mudge). Languages in this
category include {\em tcl} (Ousterhout, 2004)and {\em Perl} (Wall, et al). They are often oriented towards text
processing, with strong regular expression capabilities.
Command languages additionally add in the feature that ``statements'' can actually be commands that may have
substantial side-effects and will return exit values giving indications of success or failure [4]. The Unix shells (and
Microsoft's simple {\texttt{COMMAND.COM}} ) are common examples, where programs are built up from a
mixture of built-in commands and any other commands available on the system. Nearly all command languages are
also scripting languages, although there was once an Ada command language shell [5] which was quite unusable due
to its requirements for strongly-typed variable declarations.
The commands developed for Unix are often designed specifically for use in shell programs: commands such as
{\texttt{expr}} and {\texttt{test}} are of little use outside of shell programs. Most of the common commands such
as {\texttt{ls}} have a variety of option switches and general behaviour that also makes them useful in shell
programs.
The Unix shell languages have worked to produce a philosophy of small programs with clearly defined and limited
scope which can be used by shell scripts to build more substantial applications [6].
\section{GUI environments}
Kulik and Clark, Kozma [] proposes a model of technology, educational activity and outcome. Prosser [] refines this
by adding in the student background in approaching the technology. Until ten years ago, many students did all their
work in a Unix environment where they were familiar with command-line interfaces and with the common Unix
tools. Teaching shell programming in this environment could be done as an extension to a familiar background.
Now, most students are more familiar with a windowing environment, and a command window is often unfamiliar.
In teaching shell programming, while the outcome, the educational activity and the technology have not changed,
the student background has. This has been a change that distances the student from the technology being used.
\section{Traditional teaching of shell programming}
Most shell programs are run from a console window, such as an {\texttt{xterm}}. Typical programs do some text
processing, file manipulations and process management [9]. These tasks are a long way from the student's
background in graphical commands, and many students find the command-line environment difficult to adjust to.
The environmental aspects of working within terminal windows and of dealing with terminal I/O tend to interfere
with the concepts being taught, of small applications glued together with command language constructs such as the
pipeline. In the ``old'' days, before windowing environments became ubiquitous this was not an issue, since the shell
programs were run in the same environment that students were used to.
\section{Scripting languages and X}
A common way of handling X applications from scripting languages is to map the low-level C function calls into
script functions. The {\em tclMotif} system is a typical example: the C function calls to create and manage Motif
widgets are mapped into {\em tcl} commands [10]. The Desktop Korn Shell does the same with Motif widgets
mapped onto Korn shell commands [11]. The {\em tcl/Tk} system does essentially the same, mapping Tk widgets
into {\em tcl} [2] (the Tk widgets were essentially designed to work with {\em tcl}, unlike Motif or most other X
widgets).
All of these bindings treat the scripting language as a ``short cut'' into the underlying C widgets. The programmer
has to adopt the windows object style of programming: create widgets, install event handlers and then
wait for these event handlers to be called. This is a valid and important programming style; however, it is not the
paradigm of command language programming.
\section{XScript}
For some years the author has been using small graphical applications originally proposed in the XScript system
[12]. This consists of a number of commands that are often modelled on shell commands, but adapted to a graphical
environment. For example, the command {\texttt{ask}} presents its command line arguments in a question dialog
box. If ``yes'' is selected, it acts like {\texttt{expr}} and writes a ``1'' to standard output and terminates with an exit
code of ``0''. This can be used in a shell script by e.g.
{\tt \begin{verbatim}
if ask Remove $file? > /dev/null
then
rm $file
fi
\end{verbatim}}
The ``scriptlets'' (to coin a phrase) are designed to work in shell programs, and conform to the Unix philosophy of
small cooperative programs. Where appropriate they read from standard input and write to standard output, so they
can be placed in pipelines or in command substitution. They return suitable exit codes so they can be used in
conditional expressions.
if ask Remove file “$file”?
Ask a question
ask
then
rm “$file”
fi
warn
Post a warning dialog if [ ! -f “$file” ]
then
warn File “$file” not found
fi
cat
ask
Ask a question
if ask Remove file “$file”?
then
rm “$file”
fi
list
Display a list of lines
read from standard
input. When a line is
selected, write the
selection to standard
output
ls *.java | list | read file
buttons
Display a text line
above a set of buttons.
When a button is
pressed write its label
to standard output
choice=`echo “Yes
No
Maybe” |
buttons “Make a choice”`
Display lines of text in echo “Line1
a textbox
Line2
Line3” | cat
\section{Example use}
A (traditional) simple and common shell program is a restricted interpreter that can provide a menu system for naive
users {\tt \begin{verbatim}
while true
do
ls
echo Enter file name
read file
case $file in
*.txt) vi $file;;
*.java) javac $file;;
*.class) java $file;;
esac
done
\end{verbatim}}
This script uses a command line interface, writing to standard output and reading from standard input. It requires the
user to type file names.
A GUI based version can use the scriptlets above, and any other X Window applications that are suitable (such as
{\texttt{xterm}})
{\tt \begin{verbatim}
while true
do
file=`ls | list`
case $file in
*.txt) xterm -e vi $file;;
*.java) javac $file 2>&1 | cat;;
*.class) java $file;
esac
done
\end{verbatim}}
This uses the scriptlets {\texttt{list}} to show the files in the current directory, {\texttt{cat}} to show the results of
the compilation, and and ordinary {\texttt{xterm}} to run an editor ({\texttt{vi}}).
An image dump of this running is shown in Figure 2.
\begin{figure*}
\centering
\epsfig{file=fileman2.eps}
\caption{Current scriptlets}
\end{figure*}
\section{ Shell features}
As can be seen from the example above, the scriplets can be used in common shell
constructs such as
\begin{itemize}
\item
Error reporting
\item
Conditional statements and while loops
\item
I/O redirection
\item
Pipelines
\item
Command substitution (the ``grave'' command)
\end{itemize}
The shell interpreter examples also show that using scriptlets results in programs similar in structure to characterbased shell programs, so that there is no need to learn additional programming techniques apart from those needed
by the scripting/command paradigms. In particular, there is no need to learn any of the X Window programming
techniques (while there is value in learning such techniques, they belong to a different paradigm, not appropriate to
scripting or command languages).
The command interpreter example can also be used to show more subtle aspects of shell
programming. The example given above maps {\texttt{stderr}} onto {\texttt{stdout}} (2$>$\&1) in order to pass
error output from a java compile through a pipeline into the {\texttt{cat}} scriptlet.
It also shows that an {\texttt{xterm}} can be used to run ordinary character-based commands. In the example, the
{\texttt{vi}} editor is persistent, so the terminal window sticks around. If however the students
try something like {\texttt{ xterm -e /bin/cat file}} to show the contents of a file, then they discover that once the
{\texttt{/bin/cat}} process terminates, the {\texttt{xterm}} window disappears! Some will discover the recently
added {\texttt{xterm}} option of {\texttt{-hold}} (at least, in XFree86). Others will use another shell script such as
{\texttt{run\_and\_wait}}:
{\tt \begin{verbatim}
# run_and_wait
# run a command and then wait for the user
# to press return
shift
eval $*
echo 'Press <return> to exit'
read x
\end{verbatim}}
which can be called by
{\texttt{xterm -e run\_and\_wait /bin/cat \$file}}
A drawback of the example scriptlet interpreter is that the list is recreated on each loop iteration, which will result in
``flashing'' of repeated scriplets (a similar effect happens with the character-based version, which in practise would
call {\texttt{clear}} to redraw the list in an empty screen). However, the {\texttt{while}} loop itself is a command,
and can be part of a pipeline: this allows a persistent source to feed values into a loop:
{\tt \begin{verbatim}
ls | list -persistent |
while read file
do
case \$file in
*.txt) xterm -e vi $file;;
*.java) javac \$file 2>\&1 | cat;;
*.class) java \$file;;
esac
done
\end{verbatim}}
This shows a consistency of approach by the shell language designers (the {\texttt{while}} construct is just another
command with redirectable I/O) which may be hard to demonstrate otherwise.
\section{Implementation}
The scriptlets have been implemented in a variety of languages. Originally they were written in {\em tclMotif}, a
{\em tcl} binding of the Motif widgets [10]. They have also been written in {\em tcl/Tk}, as a more open-source
system [2]. The current versions are written in Java [13], using the Swing widgets [14]. In all languages, they are
{\em small}: the Java version of {\texttt{list}} is less than 200 lines of source code, including comments and blank
lines.
The original scriptlets used X-Window and {\em tcl/Tk} specific mechanisms to extend the communication
mechanisms beyond those available in the Unix shells. For example, the {\em tcl/Tk} {\texttt{send}} command
could be used to overcome the uni-directional nature of pipelines. However these move beyond the accepted canon
of shell programming techniques.
The desire for such extensions arises quite naturally. For example, if thefile manager is extended to include a
``change directory'', then it would be necessary to show the list of files in the new directory. This is not hard where
{\texttt{ls | list}} is shown each time within a loop. However, with the persistent version {\texttt{ls | list | while read
file ...}} the question arises of how to refresh the {\texttt{list}} display. The pipe line communication cannot do this,
as it is unidirectional. This shows both the power of the pipeline in doing some things simply, and it weakness in not
allowing others. The only reasonable (and quite valid) solution is to call the application recursively in the new
directory, resulting in an extra new directory window.
\section{Student reaction}
The reaction of students to the scriptlets is generally positive. The scriptlets are easy to visualise and the students
can always ``see'' how their implementation is running. They report that programming using scriptlets is more fun
than working in just a terminal window. The examples given earlier show that this ``fun'' element is not gained at the
expense of standard shell programming techniques, but enhances them.
In some years, the source code of the scriptlets has been made available. When they were in {\em tclMotif} or {\em
tcl/Tk} this was generally not a problem as the students did not know {\em tcl}. However, the students did know
Java, and making the Java source code available was generally a mistake: a large set of students would prefer to
modify the Java code instead of finding anappropriate shell construct. This year, only the class files were made
available. This forced them to treat the Java programs as opaque applications, just like any other Unix command
Some students discussed the possibilities of de-compiling the class files, but decided it was more interesting to find
shell constructs instead.
This approach led some students to find mistakes in the current implementation, such as incorrect behaviour when
the window manager ``close'' button was pressed, forcing me to fix the scriplets for everyone. Although I am an
open source advocate, I have to admit that in this case closed source led to better software and student lessons!
\section{Conclusion}
This paper has shown that it is possible to write shell programs that can use GUI applications that conform to the
Unix shell programming principles. These applications, called scriptlets, can be used by students to build windows
applications while staying within the Unix command language paradigm. Student reaction has been positive.
\section{References}
[1]
R. Mudge {\em Scripting Languages: under the hood},
www.hick.org/~raffi/tclug/
\\hfil\break
[2]
J. K. Ousterhout {\em Tcl and the Tk Toolkit}, Addison-Wesley, 1994
\hfil\break
[3]
L. Wall, T. Christiansen and J. Orwant {\em Programming Perl}, O'Reilly Pre
ss
\hfil\break
[4]
http://www.webopedia.com/TERM/c/command\_language.html
\hfil\break
[5]
{\em BUSH Guide - the Guide to Pegasoft's Business Shell}
http://www.pegasoft.com/downloads/bushguide.html
\hfil\break
[6]
M. Gancarz {\em The Unix Philosphy}, Digital Press, 1995
\hfil\break
[7]
Kosma
\hfil\break
[8]
Prosser
\hfil\break
[9]
G. Glass and K. Ables {\em Unix for Programmers and Users}, Prentice-Hall,
1999
\hfil\break[10]
J. D. Newmarch {\em A Binding of tcl to Motif}, Proc Xhibition, San Jose, 1
994
\hfil\break
[11]
Desktop Korn Shell Tutorial,
http://h30097.ww3.hp.com/docs/base/DOCUMENTATION/Dtksh/dtksh\_2.html
\hfil\break
[12]
J. D. Newmarch {\em Xscript - Shell Programming with X}, X Resource, issue
15, 1995
\hfil\break
[13]
J. Gosling, B. Joy and G. Steele {\em The Java Language Specification}, Add
ison-Wesle
y
\hfil\break
[14]
M. T. Nelson {\em Java Foundation Classes}, Nelson, 1998
Download