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.
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 that 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[1]. Languages in this category include tcl [2] and Perl [3]. 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 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 expr
and test
are of little use outside of shell
programs. Most of the common commands such as ls
have a variety of option switches and general behaviour
that also makes them useful in shell programs.
There are a few commands such that perform badly when used in shell
scripts. The ftp
client usually doesn't work at all -
it insists on talking to a user terminal and will not suffer I/O redirection.
Systems such as Expect [6] have been developed
to handle these poorly behaved programs and bring them back
into being controllable by scripting languages.
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 [7].
Kosma [] 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.
Most shell programs are run from a console window, such as
an 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.
A common way of handling X applications from scripting languages is to map the low-level C function calls into script functions. The tclMotif system is a typical example: the C function calls to create and manage Motif widgets are mapped into tcl commands [10]. The Desktop Korn Shell does the same with Motif widgets mapped onto Korn shell commands [11]. The tcl/Tk system does essentially the same, mapping Tk widgets into tcl [2] (the Tk widgets were essentially designed to work with 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, insstall 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.
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 ask
presents its
command line arguments in a question dialog box. If "yes" is
selected, it acts like 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.
if ask Remove $file? > /dev/null
then
rm $file
fi
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.
The current set of scriptlets includes
scriptlet | function | example | image |
---|---|---|---|
ask
|
Ask a question |
|
|
warn
|
Post a warning dialog |
|
|
list
|
Display a list of lines read from standard input. When a line is selected, write it to standard output and exit. An option can make this persistent |
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 |
|
|
cat
|
Display lines of text in a text box |
|
A (traditional) simple and common shell program is a restricted interpreter that can provide a menu system for naive users
while true
do
ls
echo Enter file name
read file
case $file in
*.txt) vi $file;;
*.java) javac $file;;
*.class) java $file;;
esac
done
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 xterm
)
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
This uses the scriptlets list
to show the files in the
current directory,
cat
to show the results of the compilation,
and and ordinary xterm
to run an editor
(vi
).
An image dump of this running is
As can be seen from the examples above, the scriplets can be used in common shell constructs such as
The shell interpreter examples also show that using scriptlets results in programs similar in structure to character-based 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 stderr
onto
stdout
(2>&1) in order to pass
error output from a java compile through a pipeline
into the cat
scriptlet.
It also shows that an xterm
can be used to run ordinary
character-based commands. In the example, the vi
editor is
persistent, so the terminal window sticks around. If however the students
try something like
xterm -e /bin/cat file
to show the contents of a file, then they discover that once the /bin/cat
process terminates, the xterm
window disappears! Some will discover
the recently added xterm
option of -hold
(at least,
in XFree86). Others will use another shell script such as run_and_wait
:
# run_and_wait
# run a command and then wait for the user
# to press return
shift
eval $*
echo 'Press <return> to exit'
read x
which can be called by
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 clear
to redraw the list in an empty screen).
However, the while
loop itself is a command, and can be part
of a pipeline: this allows a persistent source to feed values into a loop:
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
This shows a consistency of approach by the shell language designers
(the while
construct is just another
command with redirectable I/O) which may be hard to demonstrate otherwise.
The scriptlets have been implemented in a variety of languages. Originally they
were written in tclMotif, a tcl binding of the Motif widgets [10].
They have also been written in 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 small: the Java version of list
is less than 200 lines of source code, including comments and blank lines.
The original scriptlets used X-Window and tcl/Tk specific
mechanisms to extend the communication mechanisms beyond those available in
the Unix shells. For example, the tcl/Tk 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 the
file 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 ls | list
is shown each time within a loop.
However, with the persistent version ls | list | while read file ...
the question arises of how to refresh the list
display. The pipeline
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.
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 tclMotif or tcl/Tk this was generally not a problem as the students did not know 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 an appropriate 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!
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.
[1]
R. Mudge Scripting Languages: under the hood,
www.hick.org/~raffi/tclug/
[2]
J. K. Ousterhout Tcl and the Tk Toolkit, Addison-Wesley, 1994
[3]
L. Wall, T. Christiansen and J. Orwant Programming Perl, O'Reilly Press
[4]
http://www.webopedia.com/TERM/c/command_language.html
[5]
BUSH Guide - the Guide to Pegasoft's Business Shell
http://www.pegasoft.com/downloads/bushguide.html
[6] Don Libes, Expect
O'Reilly Press
[7]
M. Gancarz The Unix Philosphy, Digital Press, 1995
[8]
How Suite it is: Microsoft Office v.X for Mac
http://www.apple.com/macosx/applications/office/
[9]
G. Glass and K. Ables Unix for Programmers and Users, Prentice-Hall, 1999
[10]
J. D. Newmarch A Binding of tcl to Motif, Proc Xhibition, San Jose, 1994
[11]
Desktop Korn Shell Tutorial,
http://h30097.ww3.hp.com/docs/base/DOCUMENTATION/Dtksh/dtksh_2.html"
[12]
J. D. Newmarch Xscript - Shell Programming with X, X Resource, issue 15, 1995
[13]
J. Gosling, B. Joy and G. Steele The Java Language Specification, Addison-Wesley
[14]
M. T. Nelson Java Foundation Classes, Nelson, 1998