Cultured Perl: A programmer's Linux-oriented setup

Optimizing your machine for your needs

After customizing tcsh, Enlightenment, Eterm, and Emacs for a Java and Perl-oriented programming environment, Teodor shows us the configuration of his desktop in Linux. It is optimized for a Java and Perl programming setup, but doubtless other programmers will find many useful tips.

Teodor Zlatanov (, Programmer, Gold Software Systems

Teodor Zlatanov graduated with an M.S. in computer engineering from Boston University in 1999. He has worked as a programmer since 1992, using Perl, Java, C, and C++. His interests are in open source work on text parsing, 3-tier client-server database architectures, UNIX system administration, CORBA, and project management.

01 March 2001

A few years ago, I began building my programming environment in UNIX. I'm still not done! What I present here is a snapshot of my environment, but please understand that it is neither finished nor perfect. You should never stop improving your computing environment. Tinkering is fun, and you will probably learn something new in the process.

All the errors are mine, but I owe thanks to the many people who have helped me over the years. (There are too many to name.) If it weren't for their help, in person and on newsgroups, I wouldn't be writing the following article.

Getting started

This article is intended for the intermediate to advanced Linux user. Perl 5.6.0, or at least 5.005, should be installed in order to do some of the examples. The Emacs editor is mentioned and may need to be installed if you want to try the Emacs examples. The Enlightenment window manager is mentioned and may need to be installed together with the Eterm terminal emulator, but most recent window managers and terminal emulators have features similar to what Enlightenment and Eterm provide in the context of this article.

You should be comfortable with editing files, making system modifications, installing Linux packages from source, and having fun with Linux. If these tasks are unfamiliar to you, be doubly careful with everything described here, and take care to back everything up. (This is a good idea in any case.) For a refresher on installing Linux packages from source, check out the developerWorks tutorial Compiling and installing software from sources.

tcsh customization

I use tcsh as my primary login shell. It is easy to convert the examples for use by bash, zsh, or another shell. The tcsh shell is what I have used for years, but it is by no means perfect for everyone.

The tcsh shell uses several initialization (rc) files. In UNIX, rc (pronounced: "ar cee") files are files read by a program upon initialization. The rc moniker comes from the common "rc" suffix to the file name (for example, "tcshrc" for the tcsh shell, or "exrc" for the classic vi editor). The rc files are also called "dot" files sometimes because they begin with a dot in order to hide them from normal directory listings.

The tcsh shell customization I have resides in the .cshrc, .login, and .logout files. Other people use .tcshrc instead of .cshrc, but unless you use the C (csh) shell as well (and you shouldn't; tcsh is much better), the difference is irrelevant.

The .login file is the first thing executed for a login shell:

Listing 1: my .login file
stty erase \^?
echo TERM = $TERM

switch ($HOST)
    case "workmachine":
    case "homemachine":
        echo "---"
        from | tail
        mesg y
        echo "---"

The "stty erase" line sets the erase character to be the delete key. I prefer this setting because I am used to the delete key erasing backwards, but you may want to leave this out if the default suits you.

Then, an echo statement prints out the current terminal. I like this so I know if xterm capabilities are supported, but it is definitely not essential.

A switch statement follows. It is similar in form to the C switch() statement (which is after all where the C [csh] shell, and later the tcsh shell, gets its heritage). Depending on the host name, we either run fetchmail (I run this at my work machine in every login shell, since multiple copies of fetchmail don't interfere with each other), or some miscellaneous commands at home.

The home machine commands are as follows: print a fortune (try it; it's fun!); then a divisor ("---"); then the last few messages in my mailbox; then turn on the paging permissions; then print another divisor.

There is also a default case for commands that should be run everywhere. It is unused in my environment.

After the .login file, the tcsh shell goes through the .cshrc file (it prefers the .tcshrc file, but it will take .cshrc if that's all that's available).

Listing 2: my .cshrc file, part 1: shell-specific settings

The code in Listing 2 is shell-specific, meaning that it doesn't directly carry over to any other shells. Generally, shell-specific settings are set with the "set" command, whereas environment settings are set with "setenv". The path is an exception because the tcsh shell maintains $PATH and $path synchronized, so you can use either set or setenv to set the path. It's a matter of personal preference.

The opposite of set and setenv are unset and unsetenv. Only set or setenv will print out a list of the shell and environment settings.

Personally, I think that the distinction between environment and shell settings is the worst aspect of tcsh. I would use one or the other, but not both. The current design forces me to use both.

Listing 3: my .cshrc file, part 2: environment
# another switch statement
switch ($HOST)
    case "homemachine":
        # from home, I use my work machine's external network interface
	setenv CVSROOT tzz@workmachine-external:/cvsroot

        # of course, ssh is the only protocol allowed.  rsh is insecure.
	setenv CVS_RSH ssh

        # my NNTP server at home
	setenv NNTPSERVER nntp

        # give Emacs a name, for Enlightenment positioning
	alias emacs emacs -name workmachine-emacs
    case "homemachine-2":
        # same as homemachine
	setenv CVSROOT tzz@workmachine-external:/cvsroot
	setenv CVS_RSH ssh
        # but this is a Solaris machine, so use mailx (I could have used
	# OSTYPE instead of $HOST for generality)
	alias mail mailx
        # default CVS root for all machine at work.  Leave rsh as the
	# default transport.
	setenv CVSROOT tzz@workmachine:/cvsroot

The environment settings in Listing 3 are mainly concerned with setting the CVS repository root correctly. If you use CVS, this is a convenient way to set things up automatically so all CVS commands will work from any machine. Also, I give a name to the main Emacs window so that Enlightenment can position it correctly.

I could have used $OSTYPE instead of $HOST, and set up a separate switch() statement to handle Solaris; but all that for the sake of aliasing mail to mailx seems a bit excessive to me.

Listing 4: my .cshrc file, part 3: aliases

To try out the aliases defined below, just type them in at the prompt. The "abc" alias will print "foreach?" on a line by itself and wait for your input. If you enter "echo $a" for example, and then "end" at the next prompt, the "echo" command runs with 1 through 9, then A through Z, then a through z in $a.

Finally, my .logout is pretty simple. It is the list of commands executed when a login tcsh shell exits, only on my home machine. On all other machines it does nothing.

Listing 5: my .logout file
switch ($HOST)
    case "homemachine":
        # save the list of subscribed newsgroups, just in case:
        # save only the first 2000 characters of each lines (the
	# .newsrc file can have very long lines), then filter out the
	# unsubscribed newsgroups, and save the output in ~/.subbed
	cut -c 1-2000 ~/.newsrc | egrep -v "!" > ~/.subbed

        # remove any dead letter files (/bin/mail generates them)
	rm ~/dead.letter

Enlightenment and Eterm customization

My favorite window manager is Enlightenment. I like it and use it. You may not like Enlightenment ("E" from now on), but, nevertheless, your window manager will probably support most of the features I like in E. It's harder to replicate the functionality of Eterm, though the aterm program is similar in intent and effect.

Both E and Eterm use themes. Themes are eye candy, rarely useful in practice. I find them useful for Eterm, but for E I don't use themes for programming support.

The most important modification I made to E was to change the default keybindings with the e16keyedit program. I have Alt-F1 through Alt-F12 mapped to go to desk 1 through 12, so I can switch between different tasks quickly. I have aliased some desks to additional keypresses -- for instance, Alt-Shift-M takes me to my mail desktop.

Also, I have Ctrl-Alt-M start up a mail window (actually "emacs -name gnus -f gnus" since I use Gnus to read my mail). In similar fashion, I have Alt-Shift-Letter go to a specific desktop, while Ctrl-Alt-Letter starts a program that is remembered to be on that desktop.

E can remember a program's location and command line invocation. This means that if a program has a unique name, E can restart it the next time you login, or just remember its position for the next time you start it. The name is the X name of the window, usually specified with the -name parameter to the program.

Eterm uses themes to specify custom behavior. You can try out the default themes that come with Eterm (for example, "Eterm -t mutt" for a mutt-oriented terminal, or "Eterm -t trans" for a transparent Eterm). I find a transparent Eterm, set to stick in the layer below all other windows, to be very useful in everyday work. It's always available because it's sticky, it never obscures other windows, and provides nice visual relief from black and white.

You can write your own Eterm themes. Look at the Eterm documentation for further information.

Emacs customization

Emacs is more than an editor -- it's a complete editing environment, file manager, Lisp compiler and virtual machine, and much more. I like Emacs for the programming support it provides.

Listings 6 and 7 are quite complex. They use a lot of Lisp code, so you should have some understanding of Lisp before you attempt to modify them to suit your own needs. (See the Resources for Lisp help.)

Listing 6: The .emacs.gun.custom file

For help with all the settings in the emacs.gnu.custom file, use the Emacs help facility. Inside Emacs, press C-h v, then the name of the variable you want to examine. You can even customize the variable's value further from the window that comes up.

The .emacs file invokes the custom file. The .emacs file is rather large and complex, and it uses a lot of Lisp modules not included with Emacs (which can be found in Resources). I have included the majority in the Resources, but you may have to do some Web surfing to get some larger packages such as eshell.

Listing 7: The .emacs file

I have tried to comment the .emacs file thoroughly. Try to understand what each line does; use the Emacs help facility if you need help. C-h a invokes the apropos command, which will look up help based on a keyword. Also, see Resources for more information and help with Emacs.

Most importantly, take only the pieces you like. If you don't use footnotes or folding mode, that's OK. Maybe you like cycle-buffer and align instead, or something in the emacs.gnu.custom file got your attention. The Resources section will guide you further.

The rest: miscellaneous setup files

I use vim, a very powerful vi clone. Here's my vimrc file (see Resources for more information on vim and the vimrc file):

Listing 8: the .vimrc file

Below is a script I use to start up a new Emacs window. It can be adapted to other uses, but I only need it to send Emacs a USR1 signal, or start a new Emacs if one isn't running. You need the CPAN Proc::ProcessTable modules to use this script. Invoke it as "./ emacs".

Listing 9:
#!/usr/bin/perl -w

use Proc::ProcessTable;
use strict;

# get the process name
my $name = shift @ARGV or die "You must provide a process name";

# get the PID to process
my $pid = get_pid ($name);

# if we got a PID...
if (defined $pid)
 kill 'USR1', $pid or die "$pid - $!\n";
else # start a new process
 system("$name &");

# find the PID from a process table, based on a name 
sub get_pid
 my $name = shift @_;
 my $table = new Proc::ProcessTable;
 foreach my $p (@{$table->table})
  # this filters out itself
  return $p->pid if (defined $p->cmndline && 
                     $p->cmndline !~ /perl/ && 
		     $p->cmndline =~ /^$name/);
 return undef;

My XFree configuration uses xinerama with two video cards. Xinerama is a module for the XFree server that provides multiple monitor capability. This means that two monitors can be one display to the computer. Enlightenment supports xinerama -- for instance, maximizing a window will maximize it to the monitor, not to the whole display, which may be multiple monitors. Unfortunately, XFree configuration files are not portable, so mine would not be useful to anyone. You have to read the documentation for XFree and create a configuration file for your own machine.

Looking ahead

I hope this cruise through my setup has helped you to improve your own environment. It's really a matter of experimentation to find the right environment, and as I already said, the experimentation should never end.

I also hope that you learned of some new programs from this tour. If you haven't, look through the Resources and I guarantee you will find something new.

If you need help with any of the setups shown here, or need general assistance, again, the Resources can help you. Your answer has almost certainly been written already, and you just need to find it. If you are stuck, look on Usenet newsgroups, Web forums, and the manuals for the program in question.



developerWorks: Sign in

Required fields are indicated with an asterisk (*).

Need an IBM ID?
Forgot your IBM ID?

Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.


All information submitted is secure.

Dig deeper into Linux on developerWorks

ArticleTitle=Cultured Perl: A programmer's Linux-oriented setup