back in 1987 I wrote this up, to help people start to grok UNIX. Enjoy.
(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
-
- Rockledge Drive Bethesda, MD 20817