994 lines
37 KiB
HTML
994 lines
37 KiB
HTML
<!--startcut ==========================================================-->
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
|
<HTML>
|
|
<HEAD>
|
|
<title>Tom's 2 Cent Tips LG #29</title>
|
|
</HEAD>
|
|
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#A000A0"
|
|
ALINK="#FF0000">
|
|
<!--endcut ============================================================-->
|
|
|
|
<H4>
|
|
"Linux Gazette...<I>making Linux just a little more fun!</I>"
|
|
</H4>
|
|
|
|
<P> <HR> <P>
|
|
<!--===================================================================-->
|
|
|
|
<center>
|
|
<H1><font color="maroon">Tom's 2 cent Tips</font></H1>
|
|
<H4>By <a href="mailto:">Tom Bryant</a></H4>
|
|
</center>
|
|
<P> <HR> <P>
|
|
The notes listed below document the author's "show stoppers" which were
|
|
made as he learned UNIX, after working on DOS, VMS, and other systems. There
|
|
is a small chance that you will make exactly the same error, and this document
|
|
will help you to solve it. What is far more likely is that you will skim
|
|
through it, and hopefully learn one very important thing:
|
|
<P>
|
|
Almost all errors are trivial, and result from your understanding a Unix
|
|
function *almost* completely. Gross errors in understanding are very rare,
|
|
although when you hit a show stopper, you usually get the initial impression
|
|
that you are hopelessly in left field and will never understand this cryptic
|
|
operating system. Not True!! *Do not give up*!
|
|
<P>
|
|
I suppose that you have already guessed it, but the FAQs, man pages and
|
|
emacs info documentation comes with Linux, and *really* help out. You have to
|
|
really dig: there are bookshelves of documentation in the above sources. You
|
|
will probably learn more about certain topics than you wanted to, but after a
|
|
while all this knowledge begins to look good on your resume. While I have
|
|
tried to avoid overlap in this document, some does exist. It should give you
|
|
pause that there is so little overlap! A modern operating system is a complex,
|
|
many faceted beast. Take it a facet at a time and you'll get around it!
|
|
<P>
|
|
UNIX is largely free of the system crashes that plague DOS and the
|
|
MAC. This is because a user account is almost incapable of accessing the
|
|
system resources required to crash the system. When you're running in DOS or
|
|
MAC mode, you (or more often, programs that you run) can crash the system. I
|
|
once complexly wiped my hard disk while running Borland's C++ compiler. I have
|
|
never had this happen with Linux. I've never, in five years, crashed the
|
|
system so badly that I had to reset. Granted, some functions (X windows and
|
|
the modem) required a reset, but I could always get to a root virtual terminal
|
|
to shut down gracefully. I've merrily crashed VMS, other Unicies, and of
|
|
course, anything Microsoft has ever produced, from DOS 3.3 to NT. Linux is
|
|
robust.
|
|
<P>
|
|
I suppose no introduction is complete without a testimonial. Here goes: I
|
|
mentioned above that I had worked on a number of systems before embracing
|
|
Unix. Unix (especially Linux) is the best system I have *ever* worked on.
|
|
Give it a chance: it takes a while to collect a "critical mass" of Unix
|
|
commands to make the system really fly, but once you do, you'll become one of
|
|
those insufferable Unix propeller heads who claim (truthfully) that nothing
|
|
else even comes close!
|
|
<P>
|
|
Please Note: The author has made every effort to insure the correctness of
|
|
the information which follows. However, there are NO warranties, expressed or
|
|
implied, for this information. In other words, if something goes wrong, it's
|
|
your problem.
|
|
<P><HR> <P>
|
|
<H3>Contents:</H3>
|
|
<ul>
|
|
<li><a HREF="./bryant.html#add">adduser</a>
|
|
<li><a HREF="./bryant.html#ar">ar</a>
|
|
<li><a HREF="./bryant.html#bac">Backing Up</a>
|
|
<li><a HREF="./bryant.html#bas">bash</a>
|
|
<li><a HREF="./bryant.html#c">C</a>
|
|
<li><a HREF="./bryant.html#chm">chmod</a>
|
|
<li><a HREF="./bryant.html#csh">cshrc</a>
|
|
<li><a HREF="./bryant.html#fin">find</a>
|
|
<li><a HREF="./bryant.html#ftp">ftp</a>
|
|
<li><a HREF="./bryant.html#gdb">gdb</a>
|
|
<li><a HREF="./bryant.html#ima">imake</a>
|
|
<li><a HREF="./bryant.html#ker">kermit</a>
|
|
<li><a HREF="./bryant.html#log">login</a>
|
|
<li><a HREF="./bryant.html#les">less</a>
|
|
<li><a HREF="./bryant.html#lin">Linux</a>
|
|
<li><a HREF="./bryant.html#mai">mail</a>
|
|
<li><a HREF="./bryant.html#mak">make</a>
|
|
<li><a HREF="./bryant.html#mod">modem</a>
|
|
<li><a HREF="./bryant.html#net">Networking</a>
|
|
<li><a HREF="./bryant.html#nro">nroff</a>
|
|
<li><a HREF="./bryant.html#qso">qsort</a>
|
|
<li><a HREF="./bryant.html#ppp">PPP</a>
|
|
<li><a HREF="./bryant.html#rm">rm</a>
|
|
<li><a HREF="./bryant.html#set">Setup</a>
|
|
<li><a HREF="./bryant.html#swa">swapon</a>
|
|
<li><a HREF="./bryant.html#tar">tar</a>
|
|
<li><a HREF="./bryant.html#tes">test</a>
|
|
<li><a HREF="./bryant.html#tim">Time</a>
|
|
<li><a HREF="./bryant.html#use">useradd</a>
|
|
<li><a HREF="./bryant.html#vir">Virtual Terminals</a>
|
|
<li><a HREF="./bryant.html#x">X</a>
|
|
</ul>
|
|
|
|
<P><HR> <P>
|
|
Alphabetical list of utilities with one or more tips with them:
|
|
<P><HR> <P>
|
|
<a name="add"></A>
|
|
<B>adduser</B>
|
|
<P>
|
|
You can only run this from root, but it is an essential command. Almost
|
|
all of your time spent in Linux should be spent in a user account of your
|
|
own creation, as this account is prevented from executing disastrous
|
|
commands such as rm -rf /* (This cleans your disk in a disastrously
|
|
complete fashion.)
|
|
<P>
|
|
MORAL: Always run in a user account, not root unless you are doing some
|
|
system administration which will only work in root.
|
|
<P><HR> <P>
|
|
<a name="ar"></A>
|
|
<B>ar</B>
|
|
<P>
|
|
Ar creates a library file, which, after you get a utility program you'll
|
|
be using in other programs, allows you to easily access the object files
|
|
of that program. The files are created by the following command:
|
|
<PRE>
|
|
ar -r libArchiveName.a objectfile.o
|
|
</PRE>
|
|
ArchiveName is, by convention, named libArchiveName.a. However, you refer
|
|
to in your make file only by ArchiveName. e.g
|
|
<PRE>
|
|
LIBFILES = ... -lArchiveName ...
|
|
</PRE>
|
|
<P> <HR> <P>
|
|
<a name="bac"></A>
|
|
<B>Backing up. </B>
|
|
<P>
|
|
Having your system crash and not loosing valuable data is what separates
|
|
the computer pros from the also rans. Here's how I do it.
|
|
<P>
|
|
All of the software on my system is safely contained on the CD that I used
|
|
to load it in. There's no reason to back up this stuff. CDs are more
|
|
stable than any tape or disk backup I know of.
|
|
<P>
|
|
I only back up files that I have fiddled with. My programs, configuration
|
|
files, documents, etc. I have a script file, sall (save all) which goes
|
|
to each directory that I have stuff in, tars it, gzips it and then saves
|
|
it to floppy.
|
|
<P>
|
|
This stuff all fits on one 1.44 Mb disk. It represents about 730 pages of
|
|
single spaced typewritten output. That's a lot of typing. Most books
|
|
aren't that big. If you have more stuff than this, I'd suspect that 80%
|
|
of it is stuff you haven't touched in a year. You can back it up to a
|
|
disk, put the disk in a safe place and pretty much forget it. Of course,
|
|
if you gzip the result, you can usually more than triple the amount of
|
|
stuff you back up.
|
|
<P>
|
|
I have 15+ disks which I keep my backups on, and back up at the end of any
|
|
day that I have done a substantial amount of input. This gives me access
|
|
to a month or more of past versions.
|
|
<P>
|
|
You'll find your own way in this. The important thing is to *do* it.
|
|
Then you can feel almost smug when you hard disk finally dies.
|
|
<P><HR> <P>
|
|
<a name="bas"></A>
|
|
<B>bash (and ksh and sh)</B>
|
|
<P>
|
|
To set an environmental variable with bash use the following syntax:
|
|
<PRE>
|
|
VARIABLE=value
|
|
</PRE>
|
|
For example, to tell bash
|
|
that your are a vt100 type terminal, enter:
|
|
<PRE>
|
|
TERM=vt100; export TERM
|
|
</PRE>
|
|
NOTE: There are no spaces around the equal sign. This is true for
|
|
all bash commands, not just setting environmental variables.
|
|
Remember this and be saved frustration down the road.
|
|
<P><HR> <P>
|
|
<a name="c"></A>
|
|
<B>C</B>
|
|
<ol>
|
|
<li>As Unix is currently configured, there is no easy way to get a single
|
|
keystroke without using curses or changing the terminal characteristics.
|
|
Your users will just have to get used to hitting Enter after an input. If
|
|
they can't, uses curses or the GCC C manual (actually a superb reference
|
|
for C libraries well worth the $50+ bucks!)
|
|
|
|
<li>After you have output to an opened text file, it is a good idea to send a
|
|
fflush(stdout) command. This will flush the buffer and keep you from
|
|
overflowing it if you get over 2048 characters in it, which is easy to do.
|
|
|
|
<li>To use math.h functions in a c program:<BR>
|
|
Link in the math libraries by typing:
|
|
<PRE>
|
|
gcc source.cxx -lm
|
|
</PRE>
|
|
Math libraries MUST be linked in last!!! Old UNIX linker convention!
|
|
|
|
<li>When declaring pointers, every variable must be proceeded by an asterisk!
|
|
<PRE>
|
|
int *v1,
|
|
v2,
|
|
v3;
|
|
</PRE>
|
|
Results in compiler complaints of bad unary operator arguments! Correct:
|
|
<PRE>
|
|
int *v1,
|
|
*v2,
|
|
*v3;
|
|
</PRE>
|
|
<li>To capture the output of a compile which is causing problems, and
|
|
outputting reams of digital vomit, use this construct from a sh based
|
|
shell like bash:
|
|
<PRE>
|
|
gcc -c flaw.cxx &> TextCapture
|
|
</PRE>
|
|
or
|
|
<PRE>
|
|
gcc -c flaw.cxx 2> TextCapture
|
|
</PRE>
|
|
The errors will be captured in TextCapture.
|
|
|
|
<li>A static variable is initialized only once in a function. All other calls
|
|
to that function result in the existing value of the variable being used.
|
|
|
|
<li>Shifts in most Unix C compliers are actually integer divides and
|
|
multiplies by 2. Never mind what the ANSI spec says: <BR>
|
|
This code gives problems:
|
|
<PRE>
|
|
long n = 0x80000000;
|
|
for (i = 0; i < 24; i++) printf("\n n is now %lx.", n >> i);
|
|
</PRE>
|
|
n must be declared as an unsigned long for this to produce reasonable
|
|
results. The fact that n starts negative fowls the compiler up. This
|
|
also indicates that right and left shifts are implemented as divide and
|
|
multiply by 2 with the GNU C++ compiler.
|
|
|
|
<li>This is perhaps my favorite subtle error. If I only had a dollar for every
|
|
hour I've spent searching for this self imposed klutziness...
|
|
<PRE>
|
|
for (i = 0; i < upper_limit; i++);
|
|
{
|
|
this = cant_happen;
|
|
the_loop = wont_execute;
|
|
}
|
|
</PRE>
|
|
See the semi-colon at the end of the for statement line? The program
|
|
pauses for an empty loop of upper_limit cycles, and then proceeds to do
|
|
just the first installment of the loop and nothing else. It's quite easy
|
|
to to, too, even after you've been bitten a few times by it.
|
|
|
|
<li>You can core dump a program sooner than quicker by writing too much stuff
|
|
into a string, so that it doesn't end with that all important 0. e.g.:
|
|
<PRE>
|
|
double age;
|
|
char oops[52];
|
|
int len; ...
|
|
sprintf(oops,"The age of the universe in nanoseconds is %f.\n",age);
|
|
len = strlen(oops);
|
|
</PRE>
|
|
The fragment will die at the strlen call, as the string is longer than 50
|
|
characters, even if it is 10 character in the sprintf statement. The age
|
|
of the universe in nanoseconds is about 19 characters long.
|
|
|
|
<li>This code will pass a file pointer (tfile) to a function:
|
|
<PRE>
|
|
#include <stdio.h> /* fclose, fopen, printf.*/
|
|
#include <stdlib.h> /* exit. */
|
|
|
|
void main(int argc, char* argv[])
|
|
{
|
|
/* Function Prototypes:*/
|
|
|
|
int openfile(FILE** tfile);
|
|
|
|
/* Variables:*/
|
|
|
|
FILE *tfile; /* Test file.*/
|
|
|
|
/* Begin:*/
|
|
|
|
printf("Starting program. tfile = %p.\n", tfile);
|
|
openfile(&tfile);
|
|
printf("Back in main. tfile = %p\n", tfile);
|
|
fclose(tfile);
|
|
}
|
|
|
|
/* Open the file and return the pointer.*/
|
|
|
|
int openfile(FILE **tfile)
|
|
{
|
|
*tfile = fopen("junk","wb");
|
|
printf("Tfile just opened. tfile = %p, *tfile = %p.\n",
|
|
tfile, *tfile);
|
|
return 1;
|
|
}
|
|
</PRE>
|
|
<li>This code will allow you to reference an array of characters as an array
|
|
of longs without using a union:
|
|
<PRE>
|
|
int bozo(void)
|
|
{
|
|
void use_long(long *array); // Function prototype.
|
|
char *array; // The character array.
|
|
|
|
use_long((long*) array);
|
|
}
|
|
|
|
void use_long(long *array);
|
|
{
|
|
// Reference the array as longs here.
|
|
}
|
|
</PRE>
|
|
<li>Profiling:<BR>
|
|
Compile with the flag -pg (for gprof compatible output).
|
|
Link with the -pg flag AT THE END OF THE LINK LIST. e.g:
|
|
<PRE>
|
|
gcc -o run_time_image my_main.o my_other_stuff.o -pg
|
|
</PRE>
|
|
Even then, don't expect miracles. This does not work on an mpeg2 package
|
|
I found on the net.
|
|
|
|
<li>Reading in a globbed (wildcarded) file list:<BR>
|
|
If you want you program to work on all files in a directory, you can
|
|
enter "myprog *". Argc will count the number of files out there, and
|
|
argv will be the char **list of their names.
|
|
|
|
<li>The code
|
|
<PRE>
|
|
string1[i++] = string2[i];
|
|
</PRE>
|
|
Will take the nth component of string2 and put it the into the nth
|
|
component of string1, then increment i. This is how GCC and the SGI C
|
|
compiler do it.
|
|
<P>
|
|
The Motorola C compiler takes the (n + 1)th component of string2 and puts
|
|
it into the nth component of string1. I gets incremented *before* the
|
|
assignment. Safer is to just use this code:
|
|
<PRE>
|
|
string1[i] = string2[i];
|
|
i++;
|
|
</PRE>
|
|
<li>The code
|
|
<PRE>
|
|
if (index++ == NR_PTS) index = 0; // Fails to implement a circular buffer.
|
|
</PRE>
|
|
Does not implement the desired buffer. Let's say that NR_PTS is 100, and
|
|
index is 99. The comparison is made when index is 99. Index is not reset,
|
|
by then it is set to 100 by the ++. Next time, of course, the index will
|
|
be reset to 0, but by then, it's overwritten whatever was in buffer[100],
|
|
which is the 101st entry in buffer, a 100 int (or whatever) array.
|
|
<P>
|
|
use this instead:
|
|
<PRE>
|
|
if (++index == NR_PTS) index = 0; // Implements the circular buffer.
|
|
</PRE>
|
|
<li>Occasionally, if you allocate a *huge* array (I needed one 10.7 MB to
|
|
make this one happen) the program will bomb as it tries to pass the array
|
|
to another function. For example:
|
|
<PRE>
|
|
char moby[20000000]; // A really big text file.
|
|
</PRE>
|
|
There simply wasn't enough room on the C/C++ stack to hold the array,
|
|
and the program bombed as soon as it tried to access it. The compiler,
|
|
of course, didn't complain.
|
|
<P>
|
|
The fix is to malloc (or new, in C++) the array:
|
|
<PRE>
|
|
char *moby; // A really big text file.
|
|
|
|
moby = (char*) malloc(20000000);
|
|
if (moby == NULL)
|
|
{
|
|
printf("Hey! I'm not big enough to hold moby!\n");
|
|
}
|
|
</PRE>
|
|
<li>When it works on one machine and not on others, or in the debugger and
|
|
not out of it:<BR>
|
|
You might well be not initializing your variables properly. Sometimes
|
|
one machine will just happen to initialize a variable to a non lethal
|
|
value, and the others won't. See inexplicable errors item 3 as well.
|
|
|
|
<li>Inexplicable errors:<BR>
|
|
Occasionally, you will face very odd errors. A function works perfectly
|
|
*most* of the time. The rest of the time, it has very strange errors.
|
|
Variables seem to change value in a capricious way, and your frustration
|
|
index soars off of the charts. If you're a beginner, you decide that
|
|
programming is beyond you, and give up. Don't despair, quite yet. There
|
|
are a few tricks, not written in any book that I have seen, that I have
|
|
developed over the years to help you over these rough spots. In general,
|
|
try these in the order given.
|
|
<ol>
|
|
<li>Rewrite your code until it is remorselessly neat.
|
|
|
|
<li>Step through it line by line with a good debugger (I recommend
|
|
GNU's GDB for C code. It's a bit flaky (1998) for C++).
|
|
|
|
<li>If these steps did not fix the problem, try recompiling
|
|
everything with a command like:
|
|
<PRE>
|
|
rm *.o // Important!
|
|
make // Or whatever compilation command you use.
|
|
</PRE>
|
|
<li>If you have inconsistent program results, so that the program
|
|
works most of the time, and inexplicably fails occasionally,
|
|
carefully check to see that all of your variables have been
|
|
initialized properly.
|
|
|
|
<li>Sometimes the memory can be corrupted by new routines not fitting
|
|
into word boundaries on your machine. Granted, this is *not*
|
|
supposed to happen, but it does anyway, even in the best
|
|
compilers and linkers. Try declaring arrays to be 1 index larger
|
|
than they should be and see if that fixes it. (This is getting to
|
|
be a rare C error (1998)).
|
|
<ol>
|
|
<li>There are times when the program does not misbehave in the
|
|
debugger, and if you put a few diagnostic printfs in it to further
|
|
check it out, it still does not die. These temporary measures may
|
|
need to be made permanent as the extra variables you created to
|
|
let you see what is going on have pushed the memory usage
|
|
boundaries of the function to a more robust spot (i.e. to a word
|
|
boundary).
|
|
</ol>
|
|
|
|
<li>Once you think you've fixed the problem, *TEST EVERYTHING* before
|
|
you release anything.
|
|
|
|
<li>Keep at it. With practice, you can dumb yourself down to the
|
|
intelligence level of a compiler. Good Luck!
|
|
</ol></ol>
|
|
<P><HR> <P>
|
|
<a name="chm"></A>
|
|
<B>chmod </B>
|
|
<P>
|
|
The command chmod XXX .* can have unforeseen after effects. It affects
|
|
the directory you're in as well as the files in that directory! You might
|
|
find that only root can access the files, and then only after chmoding
|
|
them back to where they were supposed to be.
|
|
<P>
|
|
cpio (not often used, most Unix users use tar instead)
|
|
<P>
|
|
To use cpio, for backups, specify:
|
|
<PRE>
|
|
find (path name) [-name] | cpio -oc > (destination file and directory.)
|
|
</PRE>
|
|
To extract a cpio file:
|
|
<PRE>
|
|
cpio -i [-F (full file specification)] [-r rename files]
|
|
</PRE>
|
|
<P><HR> <P>
|
|
<a name="csh"></A>
|
|
<B>cshrc</B>
|
|
<P>
|
|
To change the erase key from ctrl h to <-, one has to add the line:
|
|
<PRE>
|
|
stty erase \x7F
|
|
</PRE>
|
|
To the .cshrc file. Unfortunately, the C shell interpreter does not
|
|
understand the sequence \x7F, and I needed to write a short C program to
|
|
insert the byte with value 127 (7F hex) at the end of the file.
|
|
<P>
|
|
To set the terminal from 'console' or 'Linux' to vt100 (needed by elm (a
|
|
mail handling utility)) on an SGI, put this line in your .cshrc file in
|
|
you SGI home directory:
|
|
<PRE>
|
|
eval `tset -s -Q vt100`
|
|
</PRE>
|
|
If your etc/ttytype file is set up to recognize vt100s, this should work.
|
|
<P>
|
|
Note this does not work on all machines. These methods were useless on
|
|
a motorola, for example
|
|
<P><HR> <P>
|
|
<a name="fin"></A>
|
|
<B>find </B>
|
|
<PRE>
|
|
find (path name) -name (file name) -print
|
|
</PRE>
|
|
wildcards at the beginning of a find names must be preceded by a \. e.g.:
|
|
<PRE>
|
|
find / -name "\*bozo*" -print
|
|
</PRE>
|
|
finds all files with the letters bozo in them. Some systems require the
|
|
quotes as well.
|
|
<P><HR> <P>
|
|
<a name="ftp"></A>
|
|
<B>ftp</B>
|
|
<P>
|
|
Make sure the line setting is binary. Zipped files will not transfer
|
|
correctly if this is not set.
|
|
<P><HR> <P>
|
|
<a name="gdb"></A>
|
|
<B>gdb (and dbx)</B>
|
|
<P>
|
|
To examine a core file:
|
|
<PRE>
|
|
gdb <executable file name> <core file name>
|
|
</PRE>
|
|
The core file name is usually "core".
|
|
<P>
|
|
To examine an array:
|
|
<PRE>
|
|
p *arrayName@number_of_bytes_you_want_to_see
|
|
</PRE>
|
|
<P> <HR> <P>
|
|
<a name="ima"></A>
|
|
<B>imake</B>
|
|
<P>
|
|
The new way of handling compiling and linking programs is with a utility
|
|
called imake. It makes programs easier to move around from machine to
|
|
machine. To use it:
|
|
<ol>
|
|
<li>Read the imake, make and xmkmf man pages. Also any README files
|
|
that came with the program you're trying to build. If you're going
|
|
to be getting into some serious program development, the emacs
|
|
info page on make is a must read.
|
|
<li>Back up everything! Source, Makefile, imakefile, etc.
|
|
<li>imake
|
|
<li>If imake doesn't work, try xmkmf
|
|
<li>If it *still* doesn't work, go back to step 0.
|
|
</ol>
|
|
<P> <HR> <P>
|
|
<a name="ker"></A>
|
|
<B>kermit (quick check of file integrity)</B>
|
|
<P>
|
|
This is true for any other data transfer protocol as well, such as ftp.
|
|
<P>
|
|
Check the size of the files that you have transfered to the target system.
|
|
If they are not the same size, something went wrong.
|
|
<P><HR><P>
|
|
<a name="log"></A>
|
|
<B>login</B>
|
|
<P>
|
|
To disable the annoying wait after an unsuccessful login, edit the file
|
|
/etc/login.defs. Change the parameter FAIL_DELAY from whatever it's set
|
|
to to 0. You'll have to be root to do this.
|
|
<PRE>
|
|
link (ln)
|
|
</PRE>
|
|
to create a symbolic link:
|
|
<PRE>
|
|
ln -s <existing file or directory> <Linked file or directory$gt;
|
|
</PRE>
|
|
e.g.:
|
|
<PRE>
|
|
ln -s OldFile NewLink
|
|
</PRE>
|
|
This creates a symbolic link name NewLink that points to OldFile.
|
|
When you access NewLink, Unix actually accesses OldFile.
|
|
<P>
|
|
Links are mainly used to save disk space, allowing yu to have the same
|
|
file in several different places without actually having maintain
|
|
multiple copies of the file.
|
|
<P><HR> <P>
|
|
<a name="les"></A>
|
|
<B>less</B>
|
|
<P>
|
|
Less can't display ANSI color escape sequences like most of the other Unix
|
|
text output utilities can. It instead tries to print them with ugly
|
|
results. On other unicies, the work around is to use the pg function, but
|
|
it's not avalible on Linux (yet).
|
|
<P><HR> <P>
|
|
<a name="lin"></A>
|
|
<B>Linux</B>
|
|
<P>
|
|
To regain text that has scrolled off of the screen, try shift-PageUp
|
|
and/or shift-PageDown. This will work on a given console until you shift
|
|
to another one. When you shift back, however, you will find that the
|
|
scrolled text has been lost.
|
|
<P>
|
|
To change from virtual console to virtual console, use left alt (only the
|
|
left alt key works on my machine) FX where FX is one of the function keys
|
|
F1 thru F6. F7 will be your X window, and isn't set up for you to log
|
|
into it, but see the note below.
|
|
<P>
|
|
When you are in X, you can move back to the text consoles by simultaneously
|
|
typing the control and alt keys, and then the function key of the virtual
|
|
console you want to be in.
|
|
<P>
|
|
To add more virtual consoles edit your /etc/ inittab file and add a line to
|
|
the getty configuration section. I added this line to inittab and it
|
|
allowed me to add another virtual console:
|
|
<PRE>
|
|
c7:456:respawn:/sbin/agetty 38400 tty7
|
|
</PRE>
|
|
This let me log into F7, but not as root. To log in as root, I added this
|
|
line to the /etc/securetty file:
|
|
<PRE>
|
|
tty7
|
|
</PRE>
|
|
I did not add further consoles, as 7 is the canonical number for the
|
|
maximum number of things you want to juggle at one time, and each virtual
|
|
console takes up precious RAM even if it is dormant.
|
|
<P>
|
|
When your screen gives weird output for lower case letters, try this:
|
|
<PRE>
|
|
echo "^V^[c"
|
|
</PRE>
|
|
(that's E C H O space control-V escape C return) to fix it.
|
|
<P><HR> <P>
|
|
<a name="mai"></A>
|
|
<B>mail</B>
|
|
<P>
|
|
To send a message with a subject:
|
|
<PRE>
|
|
mail -s "This is the subject" recipient@computer.full.ip.address < message
|
|
</PRE>
|
|
To forward your mail:
|
|
<P>
|
|
Create a file in your root directory called .forward. This file
|
|
should contain the address of the machine that you want to send the
|
|
mail to:
|
|
<P>
|
|
e.g. My .forward file reads:
|
|
<PRE>
|
|
Thomas.V.Bryant.1@gsfc.nasa.gov
|
|
</PRE>
|
|
<P> <HR> <P>
|
|
<a name="mak"></A>
|
|
<B>make</B>
|
|
<P>
|
|
The make utility *requires* that commands (as listed under a
|
|
target:dependency line) begin with a tab (ASCII 09).
|
|
<P>
|
|
If your emacs tab stops are set to under 8, emacs will insert spaces
|
|
(ASCII 32), and not a tab. This will stop make dead in its tracks.
|
|
You'll have to reset your tabs to edit a makefile.
|
|
<P>
|
|
If you break up the lines in your make file (a good idea: readability
|
|
is king!) don't put anything after your backslash (line continuation
|
|
symbol) or make will throw up on it:
|
|
<PRE>
|
|
LIBS = Lmylib Lyourlib ... \
|
|
^
|
|
|
|
|
|
|
|
No spaces or tabs or anything after here!!!
|
|
</PRE>
|
|
<P> <HR> <P>
|
|
<a name="mod"></A>
|
|
<B>modem</B>
|
|
<P>
|
|
When you install linux, your serial ports will not be configured. You have
|
|
to enable the call to /etc/rc.d/rc.serial in /etc/rc/rc.S:
|
|
<PRE>
|
|
# Run serial port setup script:
|
|
# (CAREFUL! This can make some systems hang if the rc.serial script isn't
|
|
# set up correctly. If this happens, you may have to edit the file from a
|
|
# boot disk)
|
|
#
|
|
# You need to enable this line (remove the # comment symbol):
|
|
|
|
. /etc/rc.d/rc.serial
|
|
|
|
# for your modem to work.
|
|
</PRE>
|
|
<P><HR> <P>
|
|
<a name="net"></A>
|
|
<B>Networking</B>
|
|
<P>
|
|
Installation (for Author's PPP link -- a *very* brief reminder list):
|
|
<PRE>
|
|
Load the networking module in the slakware file.
|
|
Create or copy the /etc/hosts file.
|
|
Create or copy the /etc/resolve.conf.
|
|
Edit /etc/rc.d/rc.serial.
|
|
</PRE>
|
|
|
|
Run time problems:
|
|
<P>
|
|
Try the ifconfig and netstat commands to find out what your current
|
|
network configuration is.
|
|
<P>
|
|
Use the ping command to check you connections.
|
|
<P>
|
|
Make sure that your linux kernel has drivers both for your network
|
|
card and ethernet. Networking will not work without them.
|
|
<P><HR> <P>
|
|
<a name="nro"></A>
|
|
<B>nroff</B>
|
|
<P>
|
|
Many text files are quasi-readable, and filled with control characters.
|
|
If the file turns out to be an nroff man page, you can read it with the
|
|
command:
|
|
<PRE>
|
|
groff -Tascii -man file.name | less
|
|
</PRE>
|
|
Often a variation of this command is necessary. See the man pages for
|
|
groff and grog. Grog tries to look at the file for you and suggest a
|
|
command. This is one that repays a lot of fiddling. Back up the original
|
|
file, and groff away. Usually you'll get it. Remember also that
|
|
postscript files (usually denoted by a .ps suffix) are read with the
|
|
ghostscript command from X.
|
|
<P><HR> <P>
|
|
<a name="qso"></A>
|
|
<B>qsort</B>
|
|
<P>
|
|
Here's a wierd one. The qsort function has a hard time calling it's
|
|
comparison function from a C file compiled with gcc. It works fine if gcc
|
|
thinks it's compiling a C++ file. Here's a pixel value sort I did,
|
|
heavily edited:
|
|
<PRE>
|
|
int pixCmp(pixel*, pixel*); // Return -1, 0, or 1. For the qsort call.
|
|
...
|
|
qsort(data, BigNumber, sizeof(pixel), pixCmp);
|
|
...
|
|
int pixCmp(pixel* a,
|
|
pixel* b)
|
|
{
|
|
if (a->clr > b->clr) return 1;
|
|
else if (a->clr < b->clr) return -1;
|
|
else return 0;
|
|
}
|
|
</PRE>
|
|
If the file is named pixels.c, it produces the following gcc error:
|
|
<PRE>
|
|
pixels.c: In function `readData':
|
|
pixels.c:164: warning: passing arg 4 of `qsort' from incompatible
|
|
pointer type
|
|
</PRE>
|
|
If the file is named pixels.C, it produces no errors:
|
|
<P><HR> <P>
|
|
<a name="ppp"></A>
|
|
<B>PPP</B>
|
|
<P>
|
|
Installing PPP to work with Linux can be done, but it is not trivial.
|
|
<P>
|
|
I'll describe the steps that worked for me, so that you might get a
|
|
variation on them to work for you.
|
|
<P>
|
|
Don't expect it to work perfectly the first time. You'll have to futz
|
|
with it, unless you are very lucky.
|
|
<P>
|
|
PPP must first be installed in your kernel. To check if it is there:
|
|
<PRE>
|
|
dmesg | grep -i ppp
|
|
</PRE>
|
|
You should get something that looks like this:
|
|
<PRE>
|
|
PPP: version 0.2.7 (4 channels) NEW_TTY_DRIVERS OPTIMIZE_FLAGS
|
|
PPP line discipline registered.
|
|
</PRE>
|
|
If you don't, you'll have to recompile your kernel, or get a copy of a
|
|
kernel that has ppp on it from the net. Instructions for doing this are
|
|
found in the file /usr/doc/ppp/README.linux.gz. This is where it is in my
|
|
Slackware release, yours will probably be similar. You need to read this
|
|
file now. Before you go any further. Otherwise, what follows will read
|
|
like gibberish.
|
|
<P>
|
|
Read the Readme? Good. Here's how my pppd/chat command looks:
|
|
<PRE>
|
|
/usr/sbin/pppd connect '/usr/sbin/chat "" ATDT7035551212 CONNECT "" ogin:\
|
|
tbryant word: secret_password' /dev/modem 38400 -detach crtscts modem \
|
|
defaultroute noipdefault
|
|
</PRE>
|
|
Fill in your appropriate telephone number, user ID and password.
|
|
<P>
|
|
Run the script from your root directory,unless you have given pppd suid
|
|
privileges (recommended).
|
|
<P>
|
|
When I am running the script, I do so from an X windows term, so I can
|
|
start netscape (or whatever X application I want) easily.
|
|
<P>
|
|
Once I've established the connection, then I can run netscape, ftp, or
|
|
telent to other internet connected machines.
|
|
<P>
|
|
My ISP (Internet Service Provider) assigns me a different IP address each
|
|
time I log on. This IP address can be found with ifconfig, or from the
|
|
/var/log/messages file.
|
|
<P>
|
|
The last few lines have what you need:
|
|
<PRE>
|
|
Aug 28 20:01:23 3C273 pppd[168]: local IP address 205.252.11.62
|
|
</PRE>
|
|
To log off, the PPP-HOWTO.gz document has the following logoff script:
|
|
<PRE>
|
|
#!/bin/sh
|
|
DEVICE=ppp0
|
|
#
|
|
# If the ppp0 pid file is present then the program is running. Stop it.
|
|
if [ -r /var/run/$DEVICE.pid ]; then
|
|
kill -INT `cat /var/run/$DEVICE.pid`
|
|
#
|
|
# If the kill did not work then there is no process running for this
|
|
# pid. It may also mean that the lock file will be left. You may wish
|
|
# to delete the lock file at the same time.
|
|
if [ ! "$?" = "0" ]; then
|
|
rm -f /var/run/$DEVICE.pid
|
|
echo "ERROR: Removed stale pid file"
|
|
exit 1
|
|
fi
|
|
#
|
|
# Success. Let pppd clean up its own junk.
|
|
echo "PPP link to $DEVICE terminated."
|
|
exit 0
|
|
fi
|
|
#
|
|
# The PPP process is not running for ppp0
|
|
echo "ERROR: PPP link is not active on $DEVICE"
|
|
exit 1
|
|
</PRE>
|
|
Additional hints not in the README.linux file:
|
|
<P>
|
|
All exchanges between you and you host computer will be logged in the
|
|
/var/log/messages file. Deducing what's going wrong is much easier if
|
|
you just look at the end of this file:
|
|
<PRE>
|
|
tail /var/log/messages
|
|
</PRE>
|
|
Keep trying, don't be afraid to futz around. If you're well backed up
|
|
(you *ARE*, aren't you?) you won't hurt any of you hardware, or
|
|
permanently damage any software (even this is very unlikely).
|
|
Good Luck!
|
|
<P><HR><P>
|
|
<a name="rm"></A>
|
|
<B>rm</B>
|
|
<P>
|
|
When a file absolutely refuses to go away, try surrounding its name
|
|
with quotes. This might kill it. I needed to remove a file called
|
|
#filename#. Here's how I fared.
|
|
<PRE>
|
|
rm #filename# Refused to work.
|
|
rm "#filename#" Worked.
|
|
rm '#filename#' Worked.
|
|
rm \#filename# Worked.
|
|
</PRE>
|
|
The top command worked on the older versions of Linux and SGI's IRIX.
|
|
This is probably a Posix compatibility problem that caused the more
|
|
recent versions of Linux to stop working.
|
|
<P><HR> <P>
|
|
<a name="set"></A>
|
|
<B>Setup</B>
|
|
<P>
|
|
The setup script will not run unless you are in /usr/lib/setup, and
|
|
running as root. Be careful. Back up everything before you start playing
|
|
around with this. Don't be afraid to play, however, as you can always
|
|
improve on the defaults Linux comes with.
|
|
<P><HR> <P>
|
|
<a name="swa"></A>
|
|
<B>swapon</B>
|
|
<P>
|
|
To set up a swap file, (needed for installation)
|
|
<ol>
|
|
<li>Start you new Linux box with the boot and root disks.
|
|
|
|
<li>make a partition (The rule of thumb is 1 - 2 times the size of
|
|
the RAM on your machine.) using fdisk. Be sure and set the
|
|
data type to Linux swap.
|
|
|
|
<li>Format the partition: mkswap -c </dev/partitionName>
|
|
|
|
<li>Enable swapping in /etc/rc.d/rc.S: /sbin/swapon -a
|
|
</ol>
|
|
<P><HR> <P>
|
|
<a name="tar"></A>
|
|
<B>tar</B>
|
|
<P>
|
|
To make a tar file:
|
|
<PRE>
|
|
tar -cf tarfilename filename (or directory. Directory is recursive)
|
|
</PRE>
|
|
This creates the file.
|
|
<PRE>
|
|
tar -rf tarfilename filename (or directory. Directory is recursive)
|
|
</PRE>
|
|
This appends to an existing file.
|
|
<P>
|
|
To extract a tar file:<BR>
|
|
Get into the directory where you want to have the files.
|
|
<PRE>
|
|
tar -xf (Complete filespec of the tar file to be extracted.)
|
|
</PRE>
|
|
<P><HR> <P>
|
|
<a name="tes"></A>
|
|
<B>test</B>
|
|
<P>
|
|
*NEVER* *NEVER* *NEVER* name an executable test. This is a very easy,
|
|
logical thing to do. When you try and run it, the shell will invoke it's
|
|
test utility, find nothing there, and exit silently, leaving you very
|
|
puzzled.
|
|
<P><HR> <P>
|
|
<a name="tim"></A>
|
|
<B>Time</B>
|
|
<P>
|
|
To set the system clock (CMOS) from Linux:
|
|
<P>
|
|
Set the system time from the CMOS clock, adjusting the time to correct for
|
|
systematic error, and writ- ting it back into the CMOS clock.
|
|
<P>
|
|
This option uses the file /etc/adjtime to determine how the clock changes.
|
|
It contains three numbers: The first number is the correction in seconds
|
|
per day (for example, if your clock runs 5 seconds fast each day, the
|
|
first number should read -5.0).
|
|
<P>
|
|
The second number tells when clock was last used, in seconds since
|
|
1/1/1970.
|
|
<P>
|
|
The third number is the remaining part of a second that was left over
|
|
after the last adjustment.
|
|
<P>
|
|
The following instructions are from the source code:
|
|
<ol>
|
|
<li> create a file /etc/adjtime containing as the
|
|
first and only line: '0.0 0 0.0'
|
|
|
|
<li> run clock -au or clock -a, depending on whether your CMOS is
|
|
in Universal or Local Time. This updates the second number.
|
|
|
|
<li> set your system time using the date command. mmddhhmm[yy][.ss]
|
|
|
|
<li> update your CMOS time using clock -wu (for UT) or clock -w.
|
|
|
|
<li> replace the first number in /etc/adjtime by your correction.
|
|
|
|
<li> put the command clock -au or clock -a in your /etc/rc.local,
|
|
or let cron(8) start it regularly.
|
|
</ol>
|
|
<P><HR> <P>
|
|
<a name="use"></A>
|
|
<B>useradd</B>
|
|
<P>
|
|
When a user is added, you have to make sure that the user owns, or at least
|
|
has read, write, and execute privileges on his/her home directory. If you
|
|
neglect this step, the new user will be unable to function properly, and
|
|
perhaps will not be able to log on!
|
|
<P>
|
|
The /usr/bin directory must have its privileges set to 755 in order for
|
|
users to be able to execute the UNIX commands contained therein.
|
|
<P><HR> <P>
|
|
<a name="vir"></A>
|
|
<B>Virtual Terminals:</B>
|
|
<P>
|
|
To change from terminal to terminal:
|
|
<PRE>
|
|
Left Alt + fn
|
|
</PRE>
|
|
(n is the terminal number, from 1 - 6 and f is a function key.)
|
|
<P>
|
|
To return to virtual terminal text mode from X:
|
|
<PRE>
|
|
Left Alt + Control + fn
|
|
</PRE>
|
|
n is again the number of the terminal you want.
|
|
<P>
|
|
To see text that has scrolled off of the screen:
|
|
<PRE>
|
|
Shift + Page up or Page down.
|
|
</PRE>
|
|
Moves you up and down by half a screen each time.
|
|
<P>
|
|
To see task information:
|
|
<PRE>
|
|
+ Scroll Lock
|
|
</PRE>
|
|
To see memory information:
|
|
<PRE>
|
|
Shift + Scroll Lock
|
|
</PRE>
|
|
<P> <HR> <P>
|
|
<a name="x"></A>
|
|
<B>X:</B>
|
|
<P>
|
|
There are few short X tips. You need to read much of the documentation
|
|
that is out there, and but the O'Rielly series in X and Motif if you
|
|
intend to do serious developemt. It's an extrodinary, platform
|
|
independent, system that solves some very difficult problems with
|
|
accessing system resources in a uniform way. It's also very complex, with
|
|
all sorts of redundant functions and kludges. Good Luck.
|
|
<P>
|
|
If you're going to just start getting into building user interfaces, I
|
|
suggest that you bypass X entirely, and concentrate on Java. Of course,
|
|
Java for Unix platforms is based on X, but you shouldn't have to worry
|
|
about that.
|
|
|
|
<!--===================================================================-->
|
|
<P> <hr> <P>
|
|
<center><H5>Copyright © 1998, Tom Bryant <BR>
|
|
Published in Issue 29 of <i>Linux Gazette</i>, June 1998</H5></center>
|
|
|
|
<!--===================================================================-->
|
|
<P> <hr> <P>
|
|
<A HREF="./index.html"><IMG ALIGN=BOTTOM SRC="../gx/indexnew.gif"
|
|
ALT="[ TABLE OF CONTENTS ]"></A>
|
|
<A HREF="../index.html"><IMG ALIGN=BOTTOM SRC="../gx/homenew.gif"
|
|
ALT="[ FRONT PAGE ]"></A>
|
|
<A HREF="./richardson.html"><IMG SRC="../gx/back2.gif"
|
|
ALT=" Back "></A>
|
|
<A HREF="./hughes.html"><IMG SRC="../gx/fwd.gif" ALT=" Next "></A>
|
|
<P> <hr> <P>
|
|
<!--startcut ==========================================================-->
|
|
</BODY>
|
|
</HTML>
|
|
<!--endcut ============================================================-->
|