(C)Copyright Paul B. Reiber, Jr. 1987. All Rights Reserved. Making the UNIX system easier to use. A simple yet effective way to tame the UNIX interface. One of the more common complaints that we have all heard and grown to hate is that UNIX is unweildy to the "uninitiated". UNIX currently has a relatively long (high?) learning curve. That is partially because it is so huge, and partially because the manual reads like one large quick reference card. So, how do we coerce the beast into submission? There are a number of ways. Menuing/Windowing shells, though not available in abundance, do exist, and function well in most cases. But, when it comes to UNIX, there's no way to avoid learning some Shell. Shell. There are three shells in common use today. sh - Bourne shell. The first real shell for UNIX. csh - say 'sea shell' The berkeley shell. Wondemous... ksh - Korn shell The latest. Greatest. It's sh+csh+more Shells are both user interfaces and programming languages. Do not even compare a UNIX shell to DOS's COMMAND.COM/DOLITTLE.BAT setup; UNIX shells are infinitely more flexible. One can do some relatively incredible things in shell. At one point, the official software design cycle at CMU included prototyping first in shell, then recoding in C if it wasn't fast enough. Shell programs are referred to as shell scripts, and if you give a shell script the right name it will be run when you log in. (just like autoexec.bat under DOS) The name is different depending on which shell you use... .profile for sh .login / .cshrc for csh .login / .kshrc for ksh ( I think... don't kill me if I'm wrong ) (for the shells with two names posted, first is for login shell, second is for any shell fired up, login or not) You will want to test each change to your .profile before you actually install it into the file, by actually coding the change in another file, and installing it after it works. You can get shells to test scripts as if they were your 'login' scripts via '. test-file-name' or 'source test-file-name' depending upon which shell you use. So this is where you should direct your efforts to tame UNIX. The absolute first to do is make sure you don't delete the .profile that may already be in your home directory ($HOME ... usually /usr/your-login-ID). Your friendly local systems setup man may have placed some 'magic' there. 'ls -a' will let you see files that start with a '.'; UNIX thinks its doing you a favor by hiding them from you by default. I disagree; I want to see all of the files in my listings, including the references to the current directory ('.') and the parent directory ('..'). This is my first 'taming'... to make the 'ls' file listing program work nicer. While I'm at it, I'd like 'ls' to put the listing in columns, and to put a '/' (slash) after directories, and a '*' after executable programs. And, please convert any non-printing characters to '?'. And include the size of the file (in bytes). (Is that personalized enough?) To get the 'ls' program to do this, we give it a list of command-line arguments. Each argument modifies the job the 'ls' program does slightly. For System V, (and probably ONLY for System V), these are: 'C' for columns, 'F' for type of file, 'q' for question-mark, 'a' for all, and 's' for size. So, we do 'ls -CFqas' to make ls work like I want it to. That's a lot of typing to get right every time! If UNIX stopped here, it really would be unweildly! But, what we can do is, in effect, 'attach' the arguments we like to each and every UNIX program, and even give them new names! In sh (Bourne shell), we can make a function that does this really easily. Putting it in the .profile file will insure it stays around for future sessions, but we can define functions (for this session only) at any shell prompt as well. In csh, we would define an 'alias'. Same concept. Once loaded, functions/aliases dont do disk IO to load, so they're much faster (especially if your system has a large IO load) than shell scripts and 'Batch files' and such. Sh function definitions look like this: name(){ body ; } or, for multi-line functions, name(){ body } They are called just like regular programs, and can reference their arguments via '$1', '$2', '$3', ... or '$*' for all arguments together. Also note that functions live in the current sh. (not a child, like scripts) Armed with this knowledge, we are ready to personalize our first program! The next line is legal to 'sh' on System V, and does everything we wanted: ls(){ /bin/ls -CFqas $* ; } # let's put -CFqas arguments on ls by default Now, for all those DOS users, we'll make UNIX handle the command 'dir' (although 'dir/w' will NEVER (f.l.words) be handled right by any shell...): dir(){ ls $* ; } # make a dir function that refers to the ls function Note that the dir function refers to 'ls', while the ls function refers to '/bin/ls'. If the ls function refered to ls, that would be a circular reference and lead to a relatively harmless but infinite loop when called. On the other hand, if dir referred to '/bin/ls', it would not get all those nice extra arguments. So, we are piggybacking 'dir', in effect. This is very useful, as it allows you to finely control changes to your interface, and to get exactly what you want, where you want it. Ok. Next step: verification before execution, and reporting success. UNIX has been criticized for acting too hastily and not providing positive feedback. So... rm(){ # remove files program # ask for verification ... echo " Really scrap [$*] ?" echo " (DEL to abort) (ENTER to proceed) ?\c" read a_line # if we aren't interrupted, proceed # (we could also test a_line against 'y' or such...) # do the action ... /bin/rm $* # checking/reporting the status ... (all spaces count in if statements) if [ $? = 0 ] ; then echo " Remove succeeded." else echo " Remove FAILED: return code $?." fi } Again, for the DOS users, we'll provide functions that make UNIX handle their requests as well as it can... del(){ rm $* ; } erase(){ rm $* ; } So, let's use a pipe in a shell function as well. This little doozie lets you look at a listing of files all day, if you'd like... ll(){ ls -lais $* | pg ; } How many times have you typed in ' c d/usr/joe ' rather than ' cd /usr/joe ' ? I tend to do this often, so I developed this function to allow UNIX to forgive at least some of my typos... c(){ cd `echo $1|sed 's/^d\//\//'`; } # cd $1, changing 'd/' to '/' first. Feel free to post questions and issues regarding these functions; feel free also to enhance them, and to share your own personalizations as well. I'll be posting shell scripts in one of the DL's as soon as I get the upload/download mechanism bootstrapped. My favorite is Tree(), which is a really flexible extension of sh's 'command-line processing' loop. if you type in a directory name, it goes there. Just hitting return shows you a ls of the current directory. Type in a filename and it defaults (after asking you) to running vi on it. (ah... Power!) Paul B. Reiber, Jr. CIS 72747,1004 6430 Rockledge Drive Bethesda, MD 2081