Linux Gazette Issue #6

A Publication of the Linux HomeBoy WebPage Series

"The Linux Gazette...making Linux just a little more fun...!"

Copyright (c) 1996 John M. Fisk

For information regarding copying and distribution of this material see the COPYING document.
Linux Home Boy Pages logo created using David Koblas' excellent program XPAINT 2.1.1

Table of Contents

Topics in this issue include:

News Flash!

LG Ready for FTP!!

Yup, I finally got all of this together! :-)

Thanks to all for their patience. I'm sorry that this took so long to organize. I've put the entire set of file together in a tar-gzip'ed format together with a short README. These pages are intended for free usage for any personal, educational, or non-commercial purpose. If that's you, then enjoy! Anyone wanting to use these for commercial purposes just needs to drop me a note and let me know what you'd like to use them for. See the copying.html document above.

My sincerest thanks to the folks at RedHat Commercial Linux and The Linux Journal/SSC who have graciously offered the use of their ftp services! You'll find ftp'able copies of the Linux Gazette pages at the following URL's:

Also, if anyone's interested in mirroring the Linux Gazette pages, there's a very short README included for that. Basically, I'd be delighted to have these pages mirrored and made as accessible as possible. All I ask is that you let me know that you're doing this, send me the URL for your pages, and an email address for the person taking care of them. I'll put together a page of mirror sites so that folks can find a site closest to them. Check the mirror.README for more details.

Linux Gazette now available on Pacific HiTech's Linux Archive Monthly CD-ROM!

The Linux Gazette files are now available in their entirety on Pacific HiTech's monthly "Linux Archive Monthly CD-ROM".

For those of you who haven't heard of this, it's a monthly CD-ROM put out by Pacific HiTech that contains a boatload of the latest Linux related programs and files culled from the Internet. For example, the January edition included:

If you're interested in this kind of offering, give PHT a call at:

or, +1-801-261-1024
FAX: +1-801-261-0310

So... does this mean that the 'Gazette is going commercial?


But, let me quickly add that, as you've all probably noticed, I believe that a strong commercial base is beneficial to the Linux community. I heartily support and encourage the efforts of such folks as Pacific HiTech, RedHat Commercial Linux, the Linux Journal and SSC, and O'Reilly publishers. These enterprises provide valuable services and offerings at VERY competitive rates, and many of them contribute a portion of their profits back into the non-commercial Linux development efforts.

Ok, sermon over. :-)

Have a look and enjoy!

Welcome to Issue #6 of the Linux Gazette !

Yup, that's right... I've decided for sanity's sake, to do a bit of renaming here. As of the beginning of this year, the Linux Gazette will be put out by issue, rather than by month. The reason for this is pretty obvious: I'm back in school and things look busy this semester. I honestly can't commit to putting these pages out on a monthly basis.

I'm very much indebted to all those who've written and sent material to be included in the 'Gazette. It helps a LOT and I want to thank these folks once again. However, it still takes a good deal of time to update pages, edit the material sent, and coordinate all that goes into each issue.


I'll make every effort to get something out each month but I definitely can't promise that this will happen. Thanks again for your patience and understanding! Also, you'll notice that I've changed the 'Gazette's main "Table of Contents" page a bit. The father of a child with ADDH (Attention Deficit Disorder / Hyperactivity) wrote and mentioned that this came across as demeaning to those with this condition. I had ADDH as a child and admit that I occasionally tease about this, having struggled with it myself. I want to publically apologize to all for this. I admit that it was inappropriate and in poor taste. My fundamental intention with the Linux Gazette is to provide a means of communicating ideas in a way that makes using Linux more fun, and NOT to insult or demean anyone. So, once again I appreciate your patience and understanding, AND I appreciate your letting me know when I get out of line...

Having said that, let me finish by saying that I hope you really enjoy this month's (oops...! er, this current issue :-) of the 'Gazette. A lot of folks have written in and there's a lot of great reading here! I must admit that I've learned a good deal from all the things that people have written and I hope that you do too. At the risk of sounding like a broken record, let me encourage you to drop the author(s) of these articles a note and let them know what you think! As I mentioned before, the 'Gazette is intended to encourage the free exchange of ideas and so I welcome any comments, suggestions, improvements, or followups that you feel might help.

Thanks for dropping in!



Salutations and the MailBag

Well, howdy! :-)

Happy 1996! I had a nice, albeit event-filled, Christmas break and am now glad to be back in school and starting a new semester. I wanted, once again, to say a very heart-felt "thanks!" to everyone that took the time to write. I know that y'all are pretty busy and I appreciate the time that many of you took out of busy schedules to write.

I've tried to include a number of interesting and informative letters below. Since my mailbox, at last count, has ballooned to 700+ messages over the past couple months, I can't squeeze all your messages in here :-) although I've tried hard to drop everyone at least a short note of thanks.

Let me encourage you to read these things!


There are a LOT of quick tips and excellent ideas here. I haven't set up a "mailto:" for each person that wrote, but if you find something useful then by all means drop that person a note and let them know about it. Most of all...



Kevin Pearson
Date: Sat, 06 Jan 1996 18:54:10 CST
From: Kevin Pearson <>
Subject: African American Pioneer Link

On Jan. 1st, was the release of the two newest Black Educational Video. The name of the program is called: "A Salute to Our Black Pioneers" - Profife: Dr. Charles R. Drew, Credited with saving thousands of lives daily due to his invention of plasma * and * Profile: Frederick M. Jones, invented the first refrigeration unit for long haul trucks.

We at Adonis are creating our home page at this time. We are let everyone one know about our company, which is producing Black Educational video programs. We would like to use your like address so that others can link up to your services. Also we would like our infomation be part of your information home page. If you can get back to me and see what we can do. Thank you. Kevin Pearson, President Adonis Productions

P.S. Our Home Page will be online on Martin Luther Kings Birthday


Jeremy Laidman
Date: Sat, 23 Dec 1995 22:56:45 CST
From: Jeremy Laidman <>
Subject: Another user for setterm


I hope you find this useful enough to include in the Gazette.

This is something I use in my Unix profiles to guide my eyes to previous command lines. By highlighting the prompt I can quickly tell where output from a command ends and my keystrokes begin.

For a bash shell, in my .profile I have:

  export PS1="\[`setterm -foreground green`\]\[`setterm 
                     -bold on`\]\h:\w\\$\[`setterm -default`\] "

My prompt appears as:


with the whole prompt a bright green (looks OK on a black screen). If I'm logged in as root, the $ becomes #. For more info on bash-isms, check out the bash man page. I use variants of this technique under other shells and on other versions of UNIX (see example below).

Some explanation for the curious:

The brackets \[ and \] are required to inform bash of escape sequences (as generated by setterm. Otherwise, command-lines that extend to multiple lines will not wrap quite right after a bit of editing.

Note the extra backslash escaping the $. It won't show as # for root without it. I could have enclosed the whole string in single quotes, and not had to use the extra bashslash, but this delays the execution of the 'setterm' commands to when the prompt is displayed (can be useful) rather than when it is set.

For systems without setterm, but with terminfo capabilities, use tput, replacing `setterm -foreground green` with `tput bold`, and `setterm -default` with `tput sgr0`.

For non-bash shells, the brackets \[ and \] for escape-sequences are not needed. For a non-Linux korn-shell (ksh) account I have, I use:

  export PS1="`tput bold``hostname`:\$PWD$`tput sgr0` "

This does everything except show # for root.

Congratulations on a fab publication. Most helpful. I like the quick tips idea. So much that makes more Linux useful for me has been shown to me by fellow Linuxers who just discovering things accidentally. Ideal snippets for such a publication.


Jeremy Laidman, Internet/Netware Contractor
Canberra, Australian Capital Territory    Phone: (61 6) 241 7969 (ah)

Simon Arthur
Date: Sat, 02 Dec 1995 00:07:33 CST
From: Chroma <>
Subject: FvwmWinList modification

I thought you might be interested in a cool modification I made to FvwmWinList.

I made a simple change to FvwmWinList for my own use. To make it more like the Windows 95 taskbar, I modified ButtonArray.c

In function DoButton, I changed the line


to read  


This removes the centering. I find this works much better if you have FvwmWinList on the left side of the screen as it lets you see the name of the window even if FvwmWinList is partially covered.

Here's what I have in my .fvwmrc:

*FvwmWinListBack #908090
*FvwmWinListFore Black
*FvwmWinListFont -adobe-helvetica-bold-r-*-*-10-*-*-*-*-*-*-*
*FvwmWinListAction Click1 Iconify -1,Focus
*FvwmWinListAction Click2 Iconify
*FvwmWinListAction Click3 Module "FvwmIdent" FvwmIdent
*FvwmWinListGeometry +3-48

Function "InitFunction"
        Module  "I"     FvwmWinList
Simon Arthur  

Tim Newsome
Date: Fri, 29 Dec 1995 09:38:00 CST
From: Tim Newsome <>
Subject: RE: Linux Gazette

On Thu, 28 Dec 1995, John M. Fisk wrote:

> >Dunno if the following is in one of the issues I haven't read yet, but here
> >goes. To have a background picture for X put the following at the end of your
> >xinitrc:
> >xv +root -rmode 5 background.gif -quit &
> >I can't remember what the -rmode 5 means. Probably centered in the screen.
> >Neat thing, anyway.

> Thanks for the tip!  I've actually run across this and played with 
> wallpapering the root window using xv -- very cool!  Definitely ought
> to mention this.

As for tips, I wrote this shell-script a while ago:


for logfile; do
  tail -$MAXLENGTH $logfile > $TMP
  # Don't use mv to keep the permissions the same.
  cat $TMP > $logfile
  rm -f $TMP

It simple goes through all the logfiles you specify on the commandline and trims them to a 1000 lines. (Nothing really useful, just another 2c one. I actually like the 2c tips a lot.)

> and your taking the time to write. Hope you had a merry Christmas -- > have a Happy New Year!

Same to you!


Tim Newsome. HotJava
rules. Pretending to work is almost as hard as the real thing. Linux >
Windows. question=(be||!be); answer=42; hack!=crack; IRC=fun; cogite ergo
rideo. 1+1=3 for large values of 1. CMU here I come! NO CARRIER

Kurt M. Hockenbury
Date: Fri, 08 Dec 1995 21:55:01 CST
From: Kurt M. Hockenbury <>
Subject: Linux Gazette syslog tip

In the November issue, you meantion syslog.conf. Here's a quick tip: I have a line at the end of my /etc/syslog.conf which reads

# Throw everything on tty8 as well
*.*                                                     /dev/tty8

This way, I also get a copy of *every* syslog entry on Virtual Console 8 (which I don't otherwise use - no getty running on it, etc). You can use any unused console you want.

It's handier than having to tail the various logging files, and cheaper on memory than running a "tail -f" under some shell, and uses no extra disk space.

When my hard disk makes swapping noises, I can look on VC8 and see the log of the incoming connection or mail. When I'm configuring or debugging daemons, it's easy to check what they're logging. :)

Hopefully, other may find this a useful suggestion.


snail://USA/07030/NJ/Hoboken/PO Box 5136/Kurt M. Hockenbury           [Stamp]

Lee Olds
Date: Fri, 12 Jan 1996 10:40:58 CST
From: Lee Olds <>
Subject: Minor nit in oct LG article on TRAP

Hi. Linux Gazette looks real good!

I have a small correction for the act article on TRAP. You said:

>So, what are the signals that can be trapped? The most common ones,
>I'm told are the following: 
>      0 - program exit 
>      1 - hang-up 
>      2 - user interrupt (ctrl-c) 
>      9 - kill signal from another process 

Those are probably the most commonly sent signals. All except for signal 9 could be the most commonly trapped signals as well. But signal 9 is special and can never be caught, so the shell has no way to trap it.

Lee Olds

Brian Matheson
Date: Thu, 21 Dec 1995 22:14:44 CST
From: Brian Matheson <>
Subject: Stuff

Just wanted to drop you a line and say hey again and let you know that I've become another of your avid fans! Since you mentioned that you'd be doing a little work on the ole' toy box, I thought I'd point out something in SunSite's Toys directory that's just too groovey to be overlooked: Xfishtank.

It turns your root window into a fish tank and runs beautifully in the background while I'm doing other stuff on my poor-boy's 486/33 with 8 megs of RAM, and it doesn't even complain about netscape eating up the color palette.

Another thing that I'd forgotten about but came across while trying to set up a ppp connection with our system at work is a little technique for trimming down those pesky syslogs. I don't know about you, but I usually forget about them until something doesn't work and then realize that they've grown to outrageous proportions in my absent-mindedness. So I came up with a one-liner to grep out the lines for a certain date:

grep "`date | cut -b5-10`" /var/adm/syslog | cut -b8-

Just make an alias for it and you're all set. Works great on /var/adm/messages too!

Many thanks for sharing the great work you do with the rest of us, the countless hours you spend aren't going unappreciated!

Happy Hollidays!


Liang Ng
Date: Fri, 12 Jan 1996 22:00:14 CST
From: Liang Ng <>
Subject: Re: Update of xterm title bar. Solution.

John M. Fisk writes:

> Excellent!  I've saved your message and will _definitely_ include it with
> the next edition of the LG!  Glad to see that you were able to get this
> worked out :-)  Also, thanks SO much for taking the time to write and
> offer this suggestion.  

Thanks John. I am very pleased to hear that.

BTW, here is a suggestion about xlock.

I am not using xdm. I use startx to start the X Window. When I used xlock on the X Window, I found that it was actually possible to switch to the Virtual Console (VC) from which I started X Window. i.e. xlock is broken! I, in fact anyone, was able to suspend startx by pressing ctrl-z at the VC, then kill xlock.

Solution to this: log myself out from the virtual console, before I leave my desk.

This solution obviously works. But it is a nuisance to see the closing down message at the VC when X Window is shut down later. So I created a Bash function startx() which redirect the stderr to /dev/null:

   /usr/X11/bin/startx $* 2> /dev/null

Note that the full path of the actual startx must be used or else Bash will interpret it as recursive function. Note also that alias in Bash does not carry arguments, hence I have to use function instead.

Of course, if you really want, you could do:

   /usr/X11/bin/startx $* 2> /dev/null &

Which logs you out from the VC as soon as X Window is started.


Liang S Ng

Tim Wallace
Date: Sat, 23 Dec 1995 08:43:30 CST
From: Tim Wallace <>
Subject: RE: Stuff


Here's the crontab that comes with RH2.0 and RH2.1.


# Run any at jobs every minute
* * * * * root /usr/sbin/atrun

# Make the whatis databases
21 03 * * 1 root /usr/sbin/makewhatis /usr/man /usr/X11R6/man

# Make the database
47 02 * * * root /usr/bin/updatedb --prunepaths='/tmp /proc /mnt /var/tmp 
/dev' 2> /dev/null

# Trim wtmp
45 02 * * * root find /var/log/wtmp -size +32k -exec cp /dev/null {} \;

# Remove /var/tmp files not accessed in 10 days
43 02 * * * root find /var/tmp/* -atime +3 -exec rm -f {} \; 2> /dev/null

# Remove /tmp files not accessed in 10 days
# I commented out this line because I tend to "store" stuff in /tmp
# 41 02 * * * root find /tmp/* -atime +10 -exec rm -f {} \; 2> /dev/null

# Remove formatted man pages not accessed in 10 days
39 02 * * * root find /var/catman/cat?/* -atime +10 -exec rm -f {} \; 2> 

# Remove and TeX fonts not used in 10 days
35 02 * * * root find /var/lib/texmf/* -type f -atime +10 -exec rm -f {} 
\; 2> /dev/null

# Trim log files
34 02 * * * root find /var/log/maillog -size +16k -exec /bin/mail -s "{}" 
root < /var/log/maillog \; -exec cp /dev/null {} \;
33 02 * * * root find /var/log/messages -size +32k -exec /bin/mail -s 
"{}" root < /var/log/messages \; -exec cp /dev/null {} \;
32 02 * * * root find /var/log/secure -size +16k -exec /bin/mail -s "{}" 
root < /var/log/secure \; -exec cp /dev/null {} \;
31 02 * * * root find /var/log/spooler -size +16k -exec /bin/mail -s "{}" 
root < /var/log/spooler \; -exec cp /dev/null {} \;
30 02 * * * root find /var/log/cron -size +16k -exec /bin/mail -s "{}" 
root < /var/log/cron \; -exec cp /dev/null {} \;

The wordwrapping should be un-done of course.


Tim Newsome
Date: Wed, 27 Dec 1995 17:53:03 CST
From: Tim Newsome <>
Subject: Linux Gazette


You're probably getting millions of these, but I just wanted to say the Linux Gazette absolutely positively completely rules. Just discovered it and reading from all of them. You taught me a bunch of stuff about fvwm there. :-) Dunno if the following is in one of the issues I haven't read yet, but here goes. To have a background picture for X put the following at the end of your .xinitrc:

xv +root -rmode 5 background.gif -quit &

I can't remember what the -rmode 5 means. Probably centered in the screen. Neat thing, anyway.

Keep it up!


Tim Newsome. HotJava
rules. Pretending to work is almost as hard as the real thing. Linux >
Windows. question=(be||!be); answer=42; hack!=crack; IRC=fun; cogite ergo
rideo. 1+1=3 for large values of 1. CMU here I come! NO CARRIER

Matt Welland
Date: Tue, 12 Dec 1995 15:49:22 CST
From: Matt Welland >welland@node71.tmp.medtronic.COM>
Subject: System configuration - beyound RCS


I've been using RCS for some time to control my system files but I found I needed something more. I wanted to be able to check out an entire machine configuration so I installed cvs. I checked in all the pertinent files in /etc, /usr/lib/uucp, /usr/lib/news and so forth and gave them a module name. Now I can check out any of several machine configurations each with its own hostname and setup. CVS took a little learning but if you know and understand RCS it is pretty easy. Follow the instructions that come with CVS and keep a system backup until you are confident everything is rock solid and predictable.


      | Matt Welland            | Medtronic/Micro-Rel              |
      | Design Engineer         | IC CAE group                     |

Ed Petron
Date: Sat, 30 Dec 1995 11:39:04 -0500
From: Ed Petron <>
Subject: Linux

John, I've been looking at your Linux home page and it's really great! I've got a home page devoted to technical and network computing at It's always great to "meet" another Linux afficianado. Drop me line if you get a chance. I'll be looking forward to hearing from you.

Ed Petron

Date: Fri, 15 Dec 1995 23:40:26 CST
From: Morpheus <morpheus@markwoon.student.Princeton.EDU>
Subject: RE: Comments and xterm titlebars

On Fri, 15 Dec 1995, John M. Fisk wrote:

> Hmmm... sounds interesting.  Are these shell scripts or binaries?  I've
> seen the pushd and popd programs mentioned before but have never run
> across them.  Do you recall where you picked these up?

Whoops. I just checked, and pushd and popd are shell built-ins. See how much cooler tcsh is? ;^) (Just joking, don't want to start a my-shell-is- better-than-your-shell flamewar here.)

Another neat tcsh built-in is "where" which searches your path for a file name you provide (eg. "where popd" in which case it returns "popd" is a shell built-in)

And on killing proceses, check out killall, it should come with the standard distribution. It'll kill all proceses with the name you provide (the slay alias I sent you probably only works on the first, I've never tested this). Very handy with runaway processes that spawn child processes faster than rabbits in heat.

> I'm not sure... I've not enough of a guru to know how you'd enter a 
> control or escape character from the keyboard.  I simply used a text
> editor to do this and then messed around with it after creating a 
> small shell program.

BTW, the emacs sequence for inserting control sequences is Control-q, followed by the desired control sequence. Adding this to the Nov. issue of LG will probably help out emacs users, fitting in well with your description on how to do so with vi... ;)

> Have a Merry Christmas and Happy New Year.  

You too! Pluribus Linux~~~~~

Introduction to Tcl/Tk by Jesper Pedersen

Tcl/Tk -- what is it

By Jesper Pedersen <>

In this article I'll try to describe what Tcl/Tk is, its strong points, and its draw backs. Furthermore, I'll give some examples of using tcl/tk and provide references to materials about Tcl/Tk. Finally, I'll try to help you avoid a few of the common pitfalls with using Tcl/Tk.


Tcl is an interpreter language which is very simple to learn and use. At the very beginning, John K. Ousterhout (the author of the program) didn't meant it to be a programming language in itself, but rather a glue for creating interfaces. The idea was that one should write his/her program in C and then use tcl as an interface to the code.

Despite this initial intention, Tcl has come to be used heavily as a programming language in itself, and it has turned out to be a very good language for quick and dirty programming. It's much more difficult to use it as a language for larger programs. (This requires much more dicipline and structure)


Tcl is a very simple programming language, and would never have been used for anything else, other than an interface glue language, if it weren't for its brother TK. Tk is a library of Tcl functions which create and manipulate X11 widgets like entries, listboxes, buttons, and many many other objects. Tk provides very high level X11 programming, i.e., it requires about 10-30 times fewer lines to create a graphical interface in Tk than in pure X11 programming.

Getting started

To start using Tk, you have to know just a little bit about Tcl. Though this section is quiet boring, it'll be of great value for you when using Tk in itself. (please note that Tk is only a library package to the Tcl language.) To start Tcl type tclsh. This will start the interpreter for Tcl.

Variables and Evaluation strategy

The very core of a language is variables. In tcl you set variables with the command set, and read the content of a variable, either with set or prepend the name with a dollar sign. Here is an example:
set var 10, this will set var to the value 10
set var, this will read the content of var, ie. return the value 10.
$var, this will expand to the value of var

To try this, use the command puts, which will write it's argument to standard out (stdout), try this:

set var 10
puts [set var]
puts $var
This will write 10 twice to standard out. Well what were those brackets for? In Tcl, commands inside brackets are expanded, so the evaluation strategy for the command puts [set var], is as follows:
  1. Evaluate set var which evaluates to 10
  2. Evaluate puts 10, which write 10 to standard out.

braces or quotes

That was the first part of Tcl, the second part is the differentiation between curly brackets and quotion marks ({} and "")
Lets see an example:
set var 10
puts "var is $var"
puts {the name of the variable is $var}
Executing the second line prints var is 10, while the third line prints the name of the variable is $var. Here is how it works: if the outermost delimiter is a brace, then everything inside is seen literally, whereas if the outermost delimiter is a quotion mark, then every thing inside is expanded.
puts {every thing "is [$litterals]"}
puts "here \[things\] shall be \"escaped\" !\$"
This will print every thing "is [$litterals]" and here [things] shall be "escaped" !$

Different commands require different numbers of parameters, while braces and quotes are used to group things which are meant as one parameter! I.e if you want to set var to "hello world", write set var "hello world" or set var {hello world}. In this example there is no difference between using braces or quotes. However, if you want to set var to the content of var1 plus a string you would write set var "var1 is $var1". If you had written set var {var1 is $var1} var1 wouldn't have been expanded, since it is protected by the braces.

References to Tcl

The online manual pages are the most important references in Tcl/Tk as they contain all the information you need, and it might be a very good idea to print them out. There are also a lot of places where the manual pages have been converted to HTML. Here are a few references:

Getting started with Tk

Now it's time to see what Tk is all about (That's why you read this article right?!) As I mentioned earlier, Tk is just Tcl functions used to manipulate X11 widgets. Well were do I start...

Hello world

Yes! All introductions to new programming languages offer a Hello World example, so here it comes. Please start the Tcl interpreter with support for Tk. This one is called wish or wish4.0
label .label -text "Hello World"
button .button -text "Quit" -command exit
pack .label .button
Try it!

Well what happens? Three Tk functions are called: label, button and pack. The first one creates a label with the text "Hello World". The next one create a button, gives it the title "Quit", and associates it with the Tcl command "exit". The third line maps them in a window, so you can see them on the screen.

Ok let's try to understand what this is all about. To do that, please invoke the manual page for the label command. In this you can see that the label command has several options available. The idea is that you can configure the label in several ways. All the options have a default value You can, for example, configure the color of the text, the font, the text itself (as we did in the example), and so forth. Some of the options are specific for the label command, while others are general for several different Tk functions. The specific ones are listed and described in the manual page for the label command, while the more general ones are listed and described in the manual page called options.

The last thing to understand about the label command is its first argument, which is .label in our example above. This argument is the name of the label. The name is used, when you want to place the label on the screen, or later on when you want to configure some of its properties (eg. change the text of the label).

To fully understand this, we have to learn about the packing strategy of Tk.

The Packer

The last command which was invoked in the example above was pack, if you try to run the example without this command, you will see that nothing appears on the screen. The idea is that you still need to describe how things are packed on the screen.

To see what you can do with this command, see the manual page for pack. Here are a few examples which will give you an idea of what can be done. Exchange the pack line above with each of these lines, and rerun the example:

Interaction with the user

So far the only interaction with the user has been a button which he could press to exit the program. Often, programs need a bit more interaction, so let's see how entries and check buttons work. Here is a bit code which will create a check button and an entry on the screen:
### creating two frames for the different part of the text
frame .top
frame .middle
frame .bottom
pack .top .middle .bottom

### creating the entry with a label
label .top.label -text "Please type your name:"
entry .top.entry -textvariable name
pack .top.label .top.entry -side left -padx 5

### creating the check button
checkbutton .middle.but -text "I'm good at tcl!" \
   -variable good
pack .middle.but

### creating the OK and CANCEL button
button .bottom.ok -text OK -command okCmd
button .bottom.cancel -text Cancel -command exit
pack .bottom.ok .bottom.cancel -side left

### creating the command to call when the OK 
### button is pressed
proc okCmd {} {
  global name good
  puts "Hi $name"
  if {$good} {
    puts "You are good at tcl...great"
  } else {
    puts "You should really learn Tcl, before you play with TK"

In Tk, variables for entries, check buttons, radio buttons and other widgets which require user interaction, are saved in global variables. So when I create an entry with - textvariable name then the contents of this entry is reflected in the global variable name.

In the example above, I create a procedure which is called when the OK button is pressed. The procedure definition is, in fact, very simple and very much like in C. See the manual page for proc for a full description on how it works.

In this procedure I declare the variables name and good for global variables with the global command. (Again, if you want to know more see the manual page!) In the example above you can see an example of a widget which is packed inside another. There is nothing fancy about it. The frame widget is just a container which help you pack the things in a smart way on your screen. When I have created the frame .top I can pack things inside it, and I have to name its sub widget with the .top name prefixed.

The rest of the example should be clear, but if there is something you don't understand, please see the manual page, all the information is located in them!

Programming Tcl/TK

In this section I'll give you some hints about how you can create Tcl/Tk programs.

First of all, don't start creating large applications in Tcl right away. There are several reasons for this, but the the most important one is that Tcl is a very bad language for incremental programming, when you want structure too... The best advice I can give you is to try tcl/tk out, see other applications and read about Tcl and Tk's possibility. When you've done all these things you'll understand what it can do, and then you start to design your applications before you program. The worst thing you can do in Tcl is to program a basic version of your interface, and then start to patch it until it is what you really want! I know that...I've tried it myself :-(

When you have a better understanding of Tcl, you'll find that it lacks composed types: the only types you have in Tcl are strings, list of strings, and associative arrays (also known as maps in other languages). The associative arrays can not contain arrays them self! This is a significant problem if you use Tcl as a programming language for larger programs. One solution for this problem is to create virtual modules. The idea is that you name your variables with a module prefix. If you,for example, have some part of your program which takes care of help, you may see this as a module, and variables used by this part of the program are all name something like help`variable. This strategy makes it a bit harder to expand variables since the pling character is a word separator in variables. This means that if you write $a`b, Tcl will try to expand a variable called $a. So, to expand this variable you would write ${a`b} or [set a`b].

Installing Tcl/Tk

It is very simple to install Tcl/Tk. Since you may also desire to expand your Tcl/Tk installation with additional tools like TclX, [Incr Tcl] or Tix, here is a short description of how you would do it.

Tcl/Tk versions

There are a number of different Tcl/Tk versions, so to help avoid confusion, here is a list of the differences:
Tcl 7.0 / Tk 3.0
This version should be considered outdated. If you find applications which require this version (and not Tcl 7.3 / Tk 3.6) you should look for other programs which do the same job (I believe they exist!)
Tcl 7.3 / Tk 3.6
This was the first version with really great success (I believe...) Many applications still use this one, since the next version was released only about a year ago. Many differences exist between this release and the official Tcl 7.4 / Tk 4.0 release, so applications written for this release may not work with version 7.4 / Tk 4.0
Tcl 7.4 / Tk 4.0
This is the newest official release from the author of the program and is the one that most people are currently using.
Tcl7.5a2 / Tk4.1a2
This is an alpha release of the next version of Tcl, with support of dynamic loading, and Windows (The operating system we all love to hate). You should only use this if you really want dynamic loading or need Tcl for Windows, since no new features has been added so far (as far as I know).

Other resources

Here is a list of resources you should check out if you plan to use Tcl:

Well first of all, the USENET group for Tcl/Tk is comp.lang.tcl. The traffic is heavy, but don't fear: it's worth it..!


A few extensions are worth mentioning here.


Tix is a set of Mega widgets for Tk. If you plan to use Tk you should really check out Tix. Personally, I've been using Tk for about 2 years, and when I learned about Tix I smashed my head against a wall....Tix was just the extension I needed (WE ALL DO!!!!). A mailing list exists for Tix, to subscribe, please send mail to the author Ioi Lam (). Also, be sure to check out the Tix home page for additional information.

[Incr Tcl]

[Incr Tcl] is an object orient extension for Tcl. I have never tried it, but from various USENET postings regarding Itcl, it appears that this is one of the best object oriented extensions available for Tcl.


TclX is a package which provides a lot of functions for Tcl which are useful for System Administrators. This is the packages which makes it possible to use Tcl instead of Perl.

WWW places

Tcl/Tk Resources
This is a collection of resources for Tcl/Tk.
Tcl/Tk Project At Sun Microsystems Laboratories
This is the official Tcl/Tk page
The Tcl/Tk Faq
Check this one out before you ask on the news!!
Tcl WWW Info
A lot of references for Tcl/TK
The Dotfile Generator
This is a configuration tool for emacs/tcsh/fvwm written in Tcl/Tk by ME (I just had to make a short advertise ;-)

[I want to publically thank Jesper for his very gracious offer to write this article which was no small feat. Please do not hesitate to drop him a note and send your comments, suggestions, and most of all a very hearty thanks. Also, if you're interested in joining the Dotfile Generator development team, let Jesper know -- he'll be glad to let you know how you can join this effort! Drop him a note at:

Jesper Pedersen

Thanks! --John]

Still Yet another HACK script

While doing a bit of Christmas Break reading over December I ran across a quote that is attributed to Larry Wall, author of the PERL scripting language. He's purported to have said something to the effect:

"There's always another way to do things..."

Whether apocryphal or not, there's a good deal of truth to this little saw and the contributions to an improved HACK script are ample evidence of this. For those of you tuning in late... a couple months ago I made a suggestion that, when modifying all those tricky little configuration files you've got lying around your system, you should use a shell script that would ensure that there's a backup copy of the config file made before you get your grubby little mitts all over it (and whose mom wouldn't agree with this... :-).

The shell script that I offered was the merest skeleton of a suggestion and pretty minimalistic. The November edition of the LG had a couple very significant improvedments to this. Here's a self-avowed "Yet another HACK script" that offers another robust improvement. It's authored by Dean Carpenter who graciously gave permission for this to be printed.

Please drop him a note of thanks! You should also read his opening comments in this file -- RTFM :-)


From: Dean Carpenter <>
Subject: Re: Yet another HACK script

Here's hack with the owner/group changes in it.
Now it will maintain correct user and groups perms.

#       hack file|dir
#       Edit a file, keeping an original copy in $DIST and a linked
#       copy in $CONFIG.  Uses RCS to log all changes.
#       If hacking a dir, simply make a symlink to the dir in $TREE
#       in the proper full-path dir.
#       Creates the following files :
#               A copy of the original file in /configs/original
#               A symlink to the original file in /configs/links
#               An RCS control file in /configs/RCS
#               A full-path symlink to the original file in /configs/tree
#       The full-path is to keep the directory structure available for
#       backing up with tar -h to dump actual files, not just
#       the symlinks.
#       That is, backing up with the command 
#               (cd /configs/tree ; tar -cvhf configs.tar . )
#       will create a tar file with all hack'd files in their correct
#       original locations with relative paths.
#               Dean Carpenter

# Location of directories
#       CONFIG  Storage dir for links
#       DIST    Original files go here
#       RCS     RCS control files go here
#       TREE    Full path copies of files

# Default to not being a directory


#       Make sure only root can hack
if [ "$LOGNAME" != "root" ]
        echo "hack: user not logged in as root"
        exit 1

#       Need a filename to hack
if [ "$1" = "" ]
        echo "hack: filename missing"
        exit 2

#       If it's a directory we need to link to $TREE
if [ -d $1 ]
        echo "hack: " $1 " is a directory"

#       Must be an existing file or a directory
if [ ! -f $1 ] && [ ! -d $1 ]
        echo "hack: bad filename"
        exit 3

#       Must be a real file, not a symlink
if [ -L $1 ]
        echo "hack: Must be a real file, not a symlink"
        exit 4

#       Make sure the repository exists
if [ ! -d $CONFIG ]
        echo "hack: Creating " $CONFIG
        mkdir --parents $CONFIG
        chmod 711 $CONFIG

#       And the dir to hold the original files
if [ ! -d $DIST ]
        echo "hack: Creating " $DIST
        mkdir --parents $DIST
        chmod 711 $DIST

#       And a place for the RCS files
if [ ! -d $RCS ]
        echo "hack: Creating " $RCS
        mkdir --parents $RCS
        chmod 711 $RCS

#       And finally a place for the full pathname files
if [ ! -d $TREE ]
        echo "hack: Creating " $TREE
        mkdir --parents $TREE
        chmod 711 $TREE

#       Get the name and dir of the file
BASENAME=`basename $1`
DIRNAME=`dirname $1`

#       If the DIRNAME is just here, then we want the full path
if [ "$DIRNAME" = "." ]

#       If it's only a partial dir in the path to the file, we need
#       to get the full path to the file.
if [ "$DIRNAME" != "$CURR_DIR" ]
        if [ -f "$CURR_DIR"/"$DIRNAME"/"$BASENAME" ]

#       If we're off the root, we don't want a doubled up //
if [ "$DIRNAME" = "/" ]

#       Get the original owner and group of the file to hack
OWNER=`ls -l $1 | awk ' { print $3 } ' `
GROUP=`ls -l $1 | awk ' { print $4 } ' `

#       If it's a dir, make a link in $TREE then exit
if [ "$DIR" = "yes" ]
        if [ ! -L $TREE$FILE ]
                mkdir --parents $TREE/$DIRNAME
                ln -s "$FILE" "$TREE$FILE"
                echo "hack: Linking " $FILE "to" $TREE$FILE
                chown $OWNER.$GROUP $TREE$FILE
                echo "hack: " $TREE$FILE " already exists"
        exit 0

#       Copy the original to save it before hacking it.
#       Make sure it's owned/grouped as the original is.
if [ ! -f $DIST/$BASENAME.dist ]
        cp $1 $DIST/$BASENAME.dist
        echo "hack: creating file " $DIST/$BASENAME".dist"
        chown $OWNER.$GROUP $DIST/$BASENAME.dist
elif [ -f $DIST/$BASENAME.dist ]
        echo "hack: " $DIST/$BASENAME".dist already exists"
        echo "hack: fatal error in " $DIST/$BASENAME".dist"
        exit 5

#       Create the symlink and update owner/group.
if [ -f $FILE ]
        if [ ! -L $CONFIG/$BASENAME ]
                ln -s "$FILE" "$CONFIG/$BASENAME"
                echo "hack: linking " $FILE "to " $CONFIG/$BASENAME
                chown $OWNER.$GROUP $CONFIG/$BASENAME
        if [ ! -L $TREE$FILE ]
                mkdir --parents $TREE/$DIRNAME
                ln -s "$FILE" "$TREE$FILE"
                echo "hack: linking " $FILE " to " $TREE$FILE
                chown $OWNER.$GROUP $TREE$FILE
        echo "hack: Whoa, something happened to " $1
        exit 6

#       If it's never been RCS'd before, check the file in and
#       create a logging line for it.
if [ ! -f $RCS/$BASENAME",v" ]
        ci -u $1 $RCS/$BASENAME,v

#       Check the file out and lock it
co -l $1 $RCS/$BASENAME,v

#       Make the changes

#       Check the file back in and re-own/group it
ci -u $1 $RCS/$BASENAME,v


Dean Carpenter
Areyes, Inc.  

You can drop Dean at note at

Caldera Network Desktop Review

By Edward Cameron

Caldera Network Desktop Review

Web Surfing News

E-Mail and Linux

[A number of folks have written and asked about reviews of the various Linux distributions -- Slackware, RedHat, Debian, Yggdrasil, Linux-FT, and so forth. Since I honestly don't have the diskspace, time, or technical expertise to do this justice I wanted to thank Edward Cameron for graciously offering to review one of these fine products: the Caldera Network Desktop by the Caldera Corporation.

[Ed very kindly sent a complete set of HTML documents which can be found in their entirety at the links above. The CND Review comes complete with some very nice screen dumps of the various parts of the desktop which will give you a bit of a feel for the product. The Web Surfing page provides some interesting links to Netscape plug-ins, and E-Mail and Linux gives some useful suggestions for setting up popclient and PINE for email service under Linux.

[If you have comments, suggestions, ideas, or just want to chat about this program, please don't hesitate to drop Ed a note! He can be reached at:

Edward Cameron

[If anyone else has experiences they'd like to share with setting up or using any of the various Linux distributions please drop me a note and let me know. The only proviso is that serious OS-bashing will be considered a no-no. (all verbal scuffles will be directed to the comp.os.linux.advocacy group... :-)

[Enjoy! --John]

FVWM and Audio!

By Nic Tjirkalli

FVWM and Sound Effects

The current trend for GUI based operating systems appears to be multimedia - incorporating the use of cute little sounds when a program starts or a window is maximised or minimised.

Well, there is no reason why dozing or apparently warping OSs should have the monopoly on this - the same can be done with the FVWM in X. As of verision 1.24 (release r) of the FVWM, an FvwmAudio module has been included, as a standard module. Quoting the FvwmAudio (1.0) man, the FvwmAudio module :-

"communicates with the FVWM window manager to bind audio sounds to window manager actions. Different audio queues may be assigned to any window manager action. FvwmAudio can be used with any independent audio player, and therefore requires no special audio library APIs of its own. Simple in its design, it merely binds the audio filenames to particular actions and forks off the audio player program with the appropriate filename when that action occurs."

To incorporate sound effects with the Fvwm, you will need :-
  1. A sound enabled/capable Linux System
  2. Version 1.24r, or higher, of the Fvwm
  3. An audio player utility
  4. Instructing FVWM to play the sounds of your choice

1. A sound enabled/capable Linux System

This is way out of the scope of this discussion, but there is a wealth of info out there on the net pertaining to sound and linux

2. Version 1.24r, or higher, of the Fvwm

You will need to get and compile version 1.24r (or higher) of the Fvwm, unless you already have FVWM 1.24r or higher. I have not been able to found out how to get the version number of FVWM. I have compiled and tested the sound module with version 2.0.39 of FVWM. You can download the fvwm source from Sunsite or your favourite Linux mirror.

[To find out which version of fvwm you're using you can enter the following either in an xterm or at the console -- note that what is printed to the screen is actually an error message that happens to contain the Fvwm version number.

        fvwm --version

What you'll see might be something like:

        Fvwm Ver 1.23b

        usage: fvwm [-d dpy] [-debug] [-f config_file] [-s]
        fvwm: another WM is running

Compile - have no fear, Fvwm compiles VERY EASILY and the included documentation is complete and useful.

To compile Fvwm,

  1. Pull down the Fvwm source. The file you need is :-
  2. Place the Fvwm archive file where you normally place source code - I use /usr/src.
  3. Uncompress and untar the archive as follows :-
            tar -zxvf fvwm-2.0.39.tgz
  4. Compile as follows: (also, read the included README.install file)

    1. Change into the newly created (the tar -zxvf process made it) fvwm directory, as follows :-
              cd fvwm
    2. Run xmkmf as follows :-
    3. Make the makefiles and compile the actual code, as follows :-
              make Makefiles
              make all 
    4. If the make went well, install the new Fvwm and the documentation, as follows (note, you will probably need root privileges to do the actual installation) :-
              make install

3. An audio player utility

The FvwmAudio module requires an external audio player to play sound files.


Extract from fvwm-2.0.39/modules/FvwmAudio/README

This version of FvwmAudio has builtin rplay support which does not need to invoke an external audio player to play sounds. The rplay support is enabled when FvwmAudio is compiled with HAVE_RPLAY defined (see the Imakefile) and when FvwmAudioPlayCmd is set to builtin-rplay. Rplay can be obtained via anonymous ftp at in the /pub/rplay directory and at in the /contrib/audio/rplay directory.

However, I have opted to use an external audio player (SOX) for a whole host of reasons. Pull down LSOX (the linux version of SOX) from Sunsite or your favourite mirror. The file you need is :- Lsox-linux.tar.gz in the /pub/Linux/apps/sound/convert/ directory. Compile - yes compile as follows :

  1. Pull down the SOX source. The file you need is :-

  2. Copy the Lsox-linux.tar.gz file to the directory you normally use for compilations - I use /usr/src.

  3. Uncompress and unarchive the SOX archive as follows :-
            tar -zxvf Lsox-linux.tar.gz
  4. Change to the newly created Lsox directory, as follows :-
            cd Lsox
  5. The INSTALL file says you should apply the Linux patches - IGNORE THIS all linux patches are already applied.

  6. Copy the files Makefile and pat.c into the SOX directory, as follows :-
            cp Makefile Sox/
            cp pat.c Sox/ 
  7. Change into the Sox directory and run make, as follows :-
            cd Sox
  8. After the compilation has completed, copy the sox binary to a directory in your path, I used /usr/bin. Then create symlinks for the files play and pplay, as follows :-
            cp sox /usr/bin/
            ln -s /usr/bin/sox /usr/bin/play
            ln -s /usr/bin/sox /usr/bin/pplay

4. Obtaing Sound files/Clips

A useful thing to have is a collection of .au or .wav sound files/clips to play for different FVWM events. There are loads of sites on the net to find them, including :-