Mirrors Primary (US) Issues February 2002

February 2002 Get BSD Contact Us Search BSD FAQ New BSD? DN Print Magazine BSD News BSD Mall BSD Support Source Wars Join Us

T H S M T H ' S F A T R E S From the Editor Fun With Automounting on FreeBSD Editorial by Renaud Waldura by Chris Coleman I'm writing this editorial Tired of having to login as root and type mount -t cd9660 from the classroom where I /dev/cd0c /mnt everytime you want to read a CD-ROM? am teaching Daemon News' Automounting is for you! Once properly configured (the first training class. This is goal of this document), you will only have to insert the CD the last day of class, and I into your drive, cd to /cdrom and *wham* everything am pleased to report that it happens automagically! Read More has gone very well...

Get BSD Stuff Making Friends with tcsh - Part 3 by Konrad Heuer

Konrad finishes his three part series with alias definitions, start-up files and hints concerning advanced csh and tcsh features. Read More

RADIUS Search by Bill Moran Monthly Ezine RADIUS stands for Remote Authentication Dial-In User Search Service. It's purpose is to supply information and authentication for multiple dial-in servers. If you only have a single dial-in server then you probably don't need the a single dial-in server then you probably don’t need the complexity of RADIUS. However, if you want to provide Daily Daemon News dial-in services to clients in more than one area code, you’ll probably have to rent "points of presence" from the phone February 2002 Issue of company, and the phone company will expect you to have a Dæmon News Ezine RADIUS server. Read More Published FreeBSD Week: Migrating from Linux to FreeBSD EuroBSDCon 2002 Japanese Language Support in NetBSD announced by Hal Snyder FreeBSD 4.5-RELEASE is now available The intent of this article is to introduce NetBSD’s Japanese FreeBSD Week: Interview language support to the English-speaking user. The with Robert Watson approach will be to demonstrate a few common activities Solaris on Intel creates with commentary on the progression of ideas involved. BSD opportunities Japanese language processing on a computer is more Jordan Hubbard Open complicated than English language processing, because Forum Japanese orthography involves four different writing AUUG Call for papers systems - , , kanji, and romaji - and uses many thousands of distinct characters... Read More BSD Support Forum What the heck is this? USB Keyboard Problem Multiple webservers behind one IP address ATI 3D Rage Pro and by Jan Sipke van der Veen FreeBSD X-Windows? The article discusses a network setup where multiple Panic after disabling webservers reside behind one IP address. Such a situation conflicts under 4.5-RC1 may arise when you need a specific webserver for one task Installer and a different webserver for another task, running different Installing FreeBSD-4.4 on a operating systems or webserver software. With only one IP laptop via ftp address available from the Internet, you could simply use error Network Address Translation (NAT) with port forwarding. Why is the Kernel giving However, this forces you to give each webserver an ugly a kernel trap 12 and URL with a non-standard port number. Read More reboots?

Source Wars DOSSIER and the Meta Project (Part 2) Week 22 by Rich Morin

Last month, I discussed some problems with the current state of Free and Open Source documentation. I then sketched out how DOSSIER and the Meta Project hope to resolve some of these problems. This month, I will discuss the goals and design of an online Meta system. Read More

R E G U A R C O L U M N S R E G U L A R C O L U M N S Daemon News Mall

C BSD Run FreeBSD Admin Training by Matthew Alton Starts Jan 28th FreeBSD for Your PC 2nd The immortal Isaac Asimov on at least one occasion Edition - $24 responded to an obvious question with a seemingly Sangoma PCI Card with paradoxical answer. Dr. Asimov, who held a Ph.D in Integrated T1 DSU/CSU - biochemistry, was asked why, when had written literally $799 hundreds of expository essays and books on such diverse Daemon Xing T-shirts and topics as theoretical physics, computer science, and more! psychology, he had not seen fit to write on his chosen field. Need Reseller Pricing - He answered, "It is too difficult. I know too much about it." Contact Cylogistics Read More Miscellaneous Credits Daemon's Advocate The hard-working by Greg Lehey crew Tarball In the last few years, I've talked about all kinds of Download a tar.gz BSD-related topics, but the intention is always what's version of this issue reflected in the name: advocacy. It's been some time since I discussed straightforward BSD advocacy; this month I'd like to consider whom target with advocacy, and how we handle it. Read More

The Answer Man by Gary Kline, Dirk Myers, and David Leonard

Greetings, salutations, and New Years best from your faithful Answer Team. This column addresses its usual wide variety of questions. Most are directed at the newer BSD user...but even long-time users are not current on the hows and whys of using grep. Or would rather not invest the hour or two to figure out how to get locate updating its database daily instead of weekly. If you understand the difference between the cua and tty /device files, then you may be well ahead of the majority of us BSD'ers. We make pretense at being profound; instead we attempt to answer questions and de-mystify the idea that " is impossibly hard that it is only for the hard-core nerd". Read More

Copyright © 1998-2001 DæmonNews. All Rights Reserved. February 2002 Search Submit Article Contact Us Join Us Merchandise

BSD Training

Chris Coleman

I'm writing this editorial from the classroom where I am teaching Daemon News' first training class. This is the last day of class, and I am pleased to report that it has gone very well.

I have really enjoyed teaching the class this week. The first session was a one day "Introduction to FreeBSD" class that covered almost everything in Annelise Anderson's book "FreeBSD: An Open Source OS for your PC." The next four day session, "FreeBSD System Administration", covered much of the book "FreeBSD Unleashed". In addition, we covered several things that weren't included in the books. I even managed to bring in a local expert to help teach because he was available. Greg Sutter came in and taught the class how to run PostFix, a mail transfer agent and Sendmail replacement.

I have to finish this up before the lunch break is over so the e-zine can finish publishing, and I can finish teaching, so this editorial will be shorter than most.

Since I had the class here, I asked them if they had anything to say about the training class; here are their responses.

"It was a great course, it helped me fill in a lot of gaps in my knowledge. The instructor took time to tailor it to fit my needs." - Paul Warner, Developer

"FreeBSD r0x0rs, w00t w00t" - Ralph Hitz, SP System Administrator, Germany

"I arrived on Monday with a whole list of questions and I am pleased to say that every one of them has been answered." -Iain Sinclair, Sysadmin, Santa Maria High School District

"I've taken the RedHat 252 course and this blows it away." - Phillip Benton, Unix Administrator, McDermott, Will & Emery

"Class was very informative. BSD already saved our company more than $400,000 and this class helped me consider BSD in the enterprise beyond the limitations of WebMin." - Usama Houlila, Senior Network Architect, McDermott Will & Emery

This is just the start of our training classes; we will be teaching another sysadmin class in New York soon, and have also already scheduled a BSD Security class. Check the training section of the BSD Mall for details.

-Chris Author maintains all copyrights on this article. Images and layout Copyright © 1998-2001 Dæmon News. All Rights Reserved. February 2002 Search Submit Article Contact Us Join Us Merchandise

Fun With Automounting on FreeBSD

Renaud Waldura

Tired of having to login as root and type:

# mount -t cd9660 /dev/cd0c /mnt everytime you want to read a CD-ROM? Automounting is for you! Once properly configured (the goal of this document), you will only have to insert the CD into your drive, cd to /cdrom and wham everything happens automagically!

My foray into the wonderful world of automounting started the day I got my hands on a big, noisy hard drive: I wanted the disk space for backup files and stuff, but couldn't bear the awful, high-pitched noise it generated day and night. So I configured my FreeBSD box to automount the drive whenever needed, then unmount it and spin the drive down when it wasn't used anymore.

DISCLAIMER I am by no means an amd/NFS guru, only a user of those technologies. While I believe this document to be correct and helpful, I cannot take responsibility for any prejudice that might occur following the instructions included herein. Quite the contrary, I am so unsure of myself that I will wholeheartedly welcome any correction/addition sent to me (interested parties can find my address at the top of this document).

This document is about automounting local filesystems only; network mounts are not covered by this document.

0. PRE-REQUISITES

A partition or single-partition device candidate for automounting (e.g. a CD-ROM drive, a floppy drive).

A computer running FreeBSD 4.0 or greater.

1. KERNEL CONFIGURATION

The automounter needs the NFS code to be present in your kernel. With FreeBSD 4.0 the corresponding kernel module can and will be autoloaded on demand, but if you' running an earlier version or wish to compile it statically anyway, you can do so by adding:

options NFS to your kernel configuration file (/sys/i386/conf/KERNEL). Personally I don't bother and just use the autoloading feature.

Autoloading works just fine with the GENERIC kernel shipped with FreeBSD 4.0. In other words, if you are running a stock FreeBSD 4.0 or greater installation, you're in luck, there's nothing to do.

Now for the various devices: as you probably know, at boot-time FreeBSD detects your hardware and initializes it. You can re-access the list of detected hardware after boot with the "dmesg" command. IT MUST SHOW YOUR CD-ROM/FLOPPY/ETC.

For example: fdc0: at port 0x3f0-0x3f5,0x3f7 irq 6 drq 2 on isa0 fdc0: FIFO enabled, 8 bytes threshold fd0: <1440-KB 3.5" drive> on fdc0 drive 0 is a floppy drive, and: cd0 at ahc0 bus 0 target 4 lun 0 cd0: Removable CD-ROM SCSI-2 device cd0: 4.032MB/s transfers (4.032MHz, offset 15) cd0: Attempt to query device size failed: NOT READY, Medium not present is a SCSI CD-R (rewritable CD) device. The device names, here fd0 and cd0, are important, we will use them very soon -- remember them.

2. CONFIGURING MOUNT

Before automounting your devices, we need to make sure they can be mounted manually. Insert a CD into your drive, and try as root:

# mount -v -t cd9660 /dev/cd0c /mnt

``cd0'' above should be replaced with whatever your actual device is (that's what we found out above). The mount point ``/mnt'' is a temporary mountpoint perfect for the kind of testing we're doing now. We mount the ``c'' partition, aka the whole disk.

The filesystem type (here ``cd9660'') must match whatever format your data is in on the disk. For CDs it's almost always cd9660, but for floppies you should use "msdos" instead:

# mount -v -t msdos /dev/fd0c /mnt

At this point your disk should be mounted; cd to /mnt and poke around to make sure your data is there. Then unmount the disk with:

# umount -v /mnt

Now you can edit /etc/fstab to make this mount semi-permanent. I added the following lines to mine:

/dev/cd0c /mnt/cdrom cd9660 ,noauto,nodev,nosuid 0 0 /dev/fd0c /mnt/floppy msdos rw,noauto 0 0

Make sure you specify the "noauto" option in the fourth column. Noauto in /etc/fstab means that the partition won't be mounted automatically at boot-time, definitely what you want since most of the time your CD/floppy won't be present. This flag is unrelated to the kind of on-demand automounting we're trying to do here.

Also note how the CD-ROM is mounted read-only (``ro'') without devices or setuid binaries. It's not strictly necessary but cleaner. The last columns are left to zero, since you will never backup those partitions, and they don't need to be checked with fsck(8).

This change made, create the two directories /mnt/cdrom and /mnt/floppy. Now you can merely issue:

# mount /mnt/cdrom and your CD-ROM should be mounted just as before. Poke around /mnt/cdrom, and unmount it:

# umount /mnt/cdrom

You're ready for the next step, the automounter itself.

3. CONFIGURING THE AUTOMOUNTER

The default configuration on FreeBSD 4.0 includes provisions for the automounter. Edit your /etc/rc.conf file to include these: portmap_enable=YES amd_enable=YES amd_flags="-a /.amd_mnt -c 3636 -l syslog /host /etc/amd.map"

The ``3636'' above is the timeout value in seconds: amd will unmount your filesystem after it's been quiescent for this many seconds.

Create the /.amd_mnt directory as root, although I'm not very clear on what it is used for. DO NOT create a /host directory.

Now edit the amd.map file to reflect this:

/defaults type:=host;fs:=${autodir}/${rhost};rhost:=${key}

* opts:=rw,grpid,resvport,nfsv2 localhost type:=auto;fs:=${map};pref:=${key}/ localhost/cdrom type:=program;fs:=/mnt/cdrom;\ mount:="/sbin/mount mount /mnt/cdrom";\ unmount:="/sbin/umount umount /mnt/cdrom" localhost/floppy type:=program;fs:=/mnt/floppy;\ mount:="/sbin/mount mount /mnt/floppy";\ unmount:="/sbin/umount umount /mnt/floppy"

As you can see, your CD-ROM drive will be mounted at /host/localhost/cdrom, not a very convenient location. Create a symbolic link /cdrom pointing to /host/localhost/cdrom:

# ln -s /host/localhost/cdrom /cdrom

At this point, we have implemented the following: symlink /cdrom ------> /host/localhost/cdrom | | amd.map fstab V /dev/cd0c <------/mnt/cdrom

When you first access /cdrom, amd will detect that you are really trying to access /host/localhost/cdrom and mount /mnt/cdrom. Wzap! your CD will be mounted.

4. TESTING

Reboot your box (or start the daemons by hand) to test your modifications to the startup files (purists can shutdown to single-user mode and restart from there).

Upon reboot, the output of mount should be similar to this:

$ mount /dev/da0s1a on / (ufs, local, ...) procfs on /proc (procfs, local) mfs:22 on /tmp (mfs, asynchronous, local, nodev, nosuid) pid102@myhost:/host on /host (nfs)

Also try ``amq'' it's fun:

$ amq / root "root" dengue:(pid102) /host toplvl /etc/amd.map /host /host/localhost auto /etc/amd.map /host/localhost

Amd has attached itself as a NFS server to the /host branch. Insert a CD in the drive and cd to /cdrom, it should be mounted automatically:

$ mount /dev/da0s1a on / (ufs, local, ...) procfs on /proc (procfs, local) mfs:22 on /tmp (mfs, asynchronous, local, nodev, nosuid) pid102@dengue:/host on /host (nfs) /dev/cd0c on /mnt/cdrom (cd9660, local, nodev, nosuid, read-only)

$ amq / root "root" dengue:(pid102) /host toplvl /etc/amd.map /host /host/localhost auto /etc/amd.map /host/localhost /host/localhost/cdrom program mount /mnt/cdrom /mnt/cdrom

Note that cd'ing to /host/localhost or /mnt/cdrom won't do it; you have to touch /host/localhost/cdrom, either directly or through a symlink like we did, for the automounter to kick in and mount the drive.

5. SECURITY CONSIDERATIONS

Unfortunately neither portmapper nor amd, both based on RPC, enjoy a particularly good reputation in security circles. Yes, this means that configuring your system for automounting can open some potentially serious security holes.

The FreeBSD version of the portmapper tries to limit the damage by using libwrap and its configuration file /etc/hosts.allow: there you can specify what hosts are allowed to connect to the portmapper service, and thus hopefully lower the risk level.

Note that the portmap service should be denied access to explicitly; the ``twist'' command of TCP Wrappers (see hosts_options(1)) cannot be used. See http://www.freebsd.org/cgi/getmsg.cgi?fetch=1925442+1933253+/usr/local/www/db/text/2000/-questions/20000402.freebsd-questions to learn why. Hence a typical /etc/hosts.allow file would be like:

# limit access to the portmapper portmap: localhost : allow portmap: ALL : severity auth.warning : deny

But as a rule of thumb do not use any NFS-related stuff (such as amd) on a sensitive system. RPC (on top of which NFS is implemented) is a very powerful technology indeed, but its security status is, mmh, considered quite low at this time. A quick search for "portmap exploits" on any search engine should find more than enough hits to convince you.

6. FUN HACKS

Now you have almost all of the info to duplicate my solution to that big noisy hard drive mentioned in the introduction.

The drive is a SCSI device detected as da1. I disklabelled it as one big partition, newfs'ed it and moved all of /var/spool to it (see the FreeBSD handbook for more information about those operations).

In /etc/fstab I have:

# Device Mountpoint FStype Options Dump Pass# /dev/da1e /mnt/spool ufs rw,noauto 1 2 and in /etc/amd.map: localhost/spool type:=program;fs:=/mnt/spool;\ mount:="/sbin/mount mount /mnt/spool";\ unmount:="/usr/local/etc/spin-down spin-down"

/var/spool is symlinked to /host/localhost/spool. ``spin-down'' is a small shell script I wrote.

#!/bin/sh # # Spin down hard disk drive da1 if no processes are using it. # da1 is a SCSI drive with a single partition mounted on /var/spool. # The drive will be re-mounted by the amd, which will make it spin # back up. # # (c) Renaud Waldura June 2000 # if umount /mnt/spool then camcontrol stop da1 -E logger -t $0 "Disk da1 spun down" fi

That's all folks! A. ERRORS

Operation not permitted when mounting: one cannot mount a regular partition on top of another. Unmount the first partition before attempting to mount.

B. REFERENCES

The mount(8) and fstab(5) manpages.

The amd(8) and amq(8) manpages.

/etc/defaults/rc.conf for more amd options.

The FreeBSD Handbook at http://www.freebsd.org/handbook/.

C. ABOUT THE AUTHOR

Renaud Waldura is a software engineer and has been hacking FreeBSD since 1996. See http://renaud.waldura.com/doc/freebsd/ for more FreeBSD articles.

Author maintains all copyrights on this article. Images and layout Copyright © 1998-2001 Dæmon News. All Rights Reserved. February 2002 Search Submit Article Contact Us Join Us Merchandise

Making friends with C-Shell and TC-Shell -- Part III

Konrad Heuer,

Table of Contents

7. How to create your own commands 7.1 Simple alias definitions 7.2 Advanced alias definitions

8. Miscellaneous topics 8.1 Environment variables 8.2 Shell variables 8.3 Shell programming 8.4 Programmed completion 8.5 Spelling correction 8.6 Command substitution

9. Making yourself at home 9.1 Shell execution modes 9.2 Start-up files

Looking back

Part I published in the December 2001 issue of Daemon News gave a general introduction into history and tasks of Unix shells and dealt with command-line editing, command history, file name globbing and name completion in csh and tcsh.

Part II in the January 2002 issue discussed the following topics: Directory stack, input and output redirection, processes, jobs and job control.

7. How to create your own commands

7.1 Simple alias definitions

Both, csh and tcsh, allow the definition of alias commands, which can be very convenient in various situations:

Often used, long, or hard to remember commands can be shortened. Programs from directories that are not worth including in the search path can be called up without needing the absolute or relative path name. UNIX commands can be redefined to create a safer working environment. A sequence of commands can easily be invoked without creating files containing shell scripts.

For example, a frequently used command is with the option -l to create a long directory listing. It is very convenient to introduce for this the alias command ll:

% alias ll ls -l % ll compile.log -rw-r--r-- 1 joe nobody 66 Dec 17 13:10 compile.log

When analyzing the second command line the shell recognizes that ll has been defined as an alias, and replaces this expression internally with ls -l. Then the ls command gets executed.

An example of the second category is the ping utility, which is located in the directory /sbin. This directory contains tools mostly useful for the system administrator only, so a normal user would have no reason to include it in the search path. However, ping can be used to see if a remote computer is alive:

% alias ping /sbin/ping % ping www.daemonnews.org PING www.daemonnews.org (204.152.186.46): 56 data bytes 64 bytes from 204.152.186.46: icmp_seq=0 ttl=46 time=208.675 ms 64 bytes from 204.152.186.46: icmp_seq=1 ttl=45 time=214.535 ms 64 bytes from 204.152.186.46: icmp_seq=2 ttl=46 time=195.677 ms ^C --- www.daemonnews.org ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max/stddev = 195.677/206.296/214.535/7.880 ms

The system queried answers correctly; the ping command is thus then terminated by pressing Control-C. The important thing here is that after ping is registered as an alias command using alias, it no longer has to be invoked with its full path name /sbin/ping.

If the alias command is entered without an argument, a list of all registered aliases is displayed:

% alias ll (ls -l) ping /sbin/ping

Some users prefer to make their working environment more fault tolerant:

% alias rm rm -i % rm compile.log remove compile.log? y

From now on, rm will always ask for a confirmation before removing files. To override the alias temporarily, one can enter:

% \rm compile.log

The file will be removed quietly since the \ character prevents the shell from alias substitution. To permanently delete an alias, the unalias can be used:

% unalias rm

The alias command can also be invoked with only one argument; it then displays the corresponding alias definition:

% alias ll ls -l

7.2 Advanced alias definitions

The alias command ll defined in the previous section can be improved by adding a pipeline to the more utility, in order to stop output after every full screen. The solution seems to be simple:

% alias lm 'ls -l | more'

The quotes are necessary to prevent the shell from interpreting the pipeline immediately, instead of waiting for a later execution of the alias command. The invocation of lm for the working directory then works flawlessly:

% lm total 18 -rwxr-xr-x 1 joe nobody 4241 Dec 18 11:14 a.out -rw-r--r-- 1 joe nobody 66 Dec 17 13:16 compile.err -rw-r--r-- 1 joe nobody 66 Dec 17 13:10 compile.log -rw-r--r-- 1 joe nobody 0 Dec 17 13:16 compile.out -rw-r--r-- 1 joe nobody 36 Dec 17 15:40 simple.c drwxr-xr-x 2 joe nobody 512 Feb 2 1996 tb

However, if one tries to use the command lm with an argument, e.g. the name of a directory, difficulties emerge:

% lm tb tb is a directory

What happens? The shell expands this command line to

% ls -l | more tb

which indeed makes no sense, since the argument gets placed in the wrong position, and more cannot display the contents of a directory. The correct command would be of course:

% ls -l tb | more

To solve the problem, the traditional access to the history buffer mentioned in section 2.3 of part I has to be used:

% alias lm 'ls -l \!* | more' % lm tb total 226 -rw-r--r-- 1 joe nobody 277 Nov 12 13:34 Makefile -rw-r--r-- 1 joe nobody 433 Nov 12 13:34 .bas -rw-r--r-- 1 joe nobody 27928 Nov 12 13:34 bi.c -rw-r--r-- 1 joe nobody 3409 Nov 12 13:34 ci.c -rw-r--r-- 1 joe nobody 1835 Nov 12 13:34 help.c -rw-r--r-- 1 joe nobody 1633 Nov 12 13:34 io.c -rw-r--r-- 1 joe nobody 838 Nov 12 13:34 tb.c -rw-r--r-- 1 joe nobody 3986 Nov 12 13:34 tb.h -rw-r--r-- 1 joe nobody 48593 Nov 12 13:34 tb.ps -rw-r--r-- 1 joe nobody 16270 Nov 12 13:34 tb.tex -rw-r--r-- 1 joe nobody 6013 Nov 12 13:34 utils.c

The backslash character blocks the interpretation of !* at the time of alias definition. Later, when the alias command is invoked, this character string is replaced by the list of arguments actually entered. When evaluating alias commands containing history event specifications, the shell considers the command entered by the user as the last command.

Mostly all history event specifications can be used within alias definitions. For example,

% alias bak 'cp -p \!:1 \!:1.bak' creates an alias command bak which makes a backup copy of the file specified as first argument:

% bak simple.c % ls -l simple.c* -rw-r--r-- 1 joe nobody 36 Dec 17 15:40 simple.c -rw-r--r-- 1 joe nobody 36 Dec 17 15:40 simple.c.bak

8. Miscellaneous topics

8.1 Environment variables

A set of variables forms the environment of a process. These variables provide some information which may be useful for processes. The shell allows to list all environment variables as well as to change them or to add new ones. The complete environment of a parent process is passed to a child process on invocation. This means, each program started by the shell on a user's request, inherits a copy of the set of environment variables the shell owns. The command printenv gives a list of all environment variables:

% printenv PATH=/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin:/usr/games:. TERM=xterm MAIL=/var/mail/joe USER=joe HOME=/usr/home/joe SHELL=/bin/tcsh HOSTTYPE=FreeBSD VENDOR=intel OSTYPE=FreeBSD MACHTYPE=i386 SHLVL=1 PWD=/usr/home/joe LOGNAME=joe GROUP=nobody HOST=hal9000

Worthwhile to remember are especially the variables PATH, the value of which defines the search path for executable files in the system, and SHELL containing the name of the shell to invoke whenever a utility program needs to start a shell.

To add further environment variables, the setenv command can be used: % setenv EDITOR emacs

This variable tells all utilities which editor to start if necessary. Environment variables can be removed by using unsetenv:

% unsetenv EDITOR

To read out the value of an environment variable, use a leading dollar sign as for usual shell variables:

% echo $USER joe

8.2 Shell variables

Shell variables have already been introduced in section 2.1. The shell allows the use of variables which can store data. These variables are different from environment variables, they are local to the shell and not passed to child processes. Various shell variables with pre-defined meanings have already been mentioned in many sections of this article series. The informational content of a variable can lie in whether it is set or not or in its value.

Variable names must consist of letters, digits, or the underscore character; the leading character has to be a letter, and the name may not be longer than twenty characters. Variables can be of scalar or array type and may take numerical or string values:

% set three = 3 % set vowels = ( a e i o u ) % echo $three 3 % echo $vowels[2] e

It is possible to test whether a shell (or environment) variable has been set or not by using the prefix $?:

% echo $?three 1 % echo $?two 0

As can be seen from the example, if the variable is not set, the operation will return zero.

The values of some special shell and environment variables are kept identical by the shell. The variables in question are group and GROUP, home and HOME, path and PATH, shlvl and SHLVL, term and TERM and user and USER.

Some useful shell variables which are not mentioned anywhere else in the article series are:

The variable autologout my be set in tcsh to a certain number of minutes. The user will be logged out automatically after a corresponding period of inactivity. The full pathname of the working directory is kept in cwd. To prevent an interactive shell from exiting after typing Control-D (end-of-file condition), ignoreeof can be set. In tcsh, the command line editor can be put into in insert (default) or overwrite mode by setting inputmode to insert or overwrite. The variable prompt is automatically set for interactive shells and can be changed to modify the command prompt. A very useful extension of tcsh is rmstar. If this variable is set, the shell will ask the user to confirm a rm * command. The exit status of the last command is kept in status.

8.3 Shell programming

Both, csh and tcsh, offer a set of internal (built-in) commands which allow to write shell scripts looking (in a way) similar to C code. That is the reason why csh is called C shell. By the way, the T in tcsh is derived from the name of the TENEX operating system the user interface of which already provided useful command completion about 25 years ago. This impressed and influenced the author of tcsh.

A famous article csh programming considered harmful has been posted to some newsgroups years ago, and indeed, csh has had a lot of bugs and disadvantages.

In the meantime, bugs have been fixed, and tcsh behaves much better. Nevertheless, both shells should at most be used for small scripts only. The reason simply is that even tcsh is weak in advanced i/o redirection which is often needed in shell programming.

However, interactive use is a different matter, and especially tcsh is quite strong here. So, this article has a focus on interactive use.

One instruction useful not only in scripts but often also when entering commands interactively is foreach to process a sequence of arguments; e.g., to print some manual pages on a PostScript printer:

% foreach file ( /usr/share/man/man1/{csh,gcc,tcsh}.1.gz ) foreach? echo $file foreach? gunzip < $file | groff -man | lpr -Pps foreach? end /usr/share/man/man1/csh.1.gz /usr/share/man/man1/gcc.1.gz /usr/share/man/man1/tcsh.1.gz

8.4 Programmed completion

Name completion in csh and tcsh has been introduced in section 3.2. Programmed name completion is an additional feature tcsh offers and should not be confused with script programming.

Two simple examples will illustrate programmed completion. When trying to complete an argument of the commands cd or rmdir, the shell will by default offer plain files as possible completions, too. To change this, enter:

% complete cd 'p/1/d/' % complete rmdir 'p/*/d/'

From now on, for cd and rmdir, when completing a word in a given position (letter p), complete the first word (digit 1) or all words (character *) with a directory name (letter d) only.

The second example will modify the behavior of the shell when requesting completion while starting ftp sessions: % complete ftp 'p/1/(ftp.freebsd.org ftp.netbsd.org ftp.openbsd.org)/' % ftp ftp.freebsd.org

8.5 Spelling correction

Another additional feature of tcsh is spelling correction, a convenient way to handle typos. After assigning one of the values cmd or all to the shell variable correct, tcsh will offer some aid:

% set correct = cmd % moer simple.c

CORRECT>more simple.c (y|n|e|a)? yes #include main(){for(;;);}

As shown in the example, the correction can be accepted (y), or otherwise rejected (n), or the command can be edited (e) or aborted (a).

After setting correct to all, tcsh will offer correction not only for command names, but for arguments, too. This can be nerving and dangerous if entered commands create new files since the correction mechanism will treat names of non-existing files as typos.

8.6 Command substitution

Command substitution is a way to use data written by utility programs to the standard output channel directly in the shell command line. The date utility may serve as an example; it can be used to print the current time to stdout:

% date '+%H:%M:%S' 11:17:58

Now, one can use this kind of output to construct file names:

% cc simple.c >& compile.log.`date '+%H:%M:%S'` % ls -l compile.log.* -rw-r--r-- 1 joe nobody 0 Jan 15 11:23 compile.log.11:23:11

Any expression enclosed in backquotes is regarded as a command, executed, and replaced by the resulting output (newlines are replaced by spaces). It is possible to use history event specifications within backquotes.

9. Making yourself at home

9.1 Shell execution modes

Three modes of execution of a shell have to be distinguished:

1. A shell executing a script (a sequence of commands stored in a file or read from redirected stdin) is non-interactive. 2. A shell accepting commands from the keyboard is interactive. 3. A shell immediately invoked within the context of a user's login procedure is an interactive login shell.

9.2 Start-up files

Common (system-wide) shell start-up files can be used to set up a convenient environment for all users on the system, and personal start-up files allow to create an individual working environment. Furthermore, there are «shutdown» files too, getting executed during the process of logging out. Among others, typical tasks of start-up files are to set environment and/or shell variables and to define alias commands.

Table 5: Start-up and «shutdown» files used by csh and tcsh File name Use /etc/csh.cshrc Common start-up file read by all shells /etc/csh.login Common start-up file read by login shells /etc/csh.logout Common shutdown file read by login shells ~/.cshrc Personal start-up file read by all shells (csh) ~/.tcshrc Personal start-up file read by all shells (tcsh) ~/.login Personal start-up file read by login shells ~/.logout Personal shutdown file read by login shells

On invocation of a new shell, the common start-up files are read first. Thus a user can override the system-wide settings by his or her personal ones since the personal files are read subsequently. Login shells read /etc/csh.login after /etc/csh.cshrc and ~/.login after ~/.cshrc. If tcsh does not find ~/.tcshrc, it will then read ~/.cshrc. Furthermore, tcsh can be compiled in such a way that the two login files are read prior to the cshrc files (the version shell variable will then contain the option string lf).

Commands that need to be executed only once during a session should be placed in one of the login files. Typical examples are commands that affect environment variables. Instructions setting shell variables or defining aliases have to be included in the cshrc files.

By the way, don't get confused by the file /.cshrc in the root directory/. It is read by single-user shells in single-user mode only. In normal multi-user operation of the system, the file is disregarded. Modifications to /.cshrc require a lot of care since you may lock yourself out completely in single-user mode!

In general, after changing one of the start-up files, do not log out before you have been able to log in successfully on a different virtual or pseudo-terminal or in a different window. This is the best way to test and to repair the files if necessary.

Non-interactive shells read the cshrc files, too; but this can be suppress