File: bryant.html

package info (click to toggle)
lg-issue29 1-1
  • links: PTS
  • area: main
  • in suites: slink
  • size: 1,992 kB
  • ctags: 387
  • sloc: java: 758; makefile: 31; sh: 3
file content (993 lines) | stat: -rw-r--r-- 37,563 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
<!--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 &lt;stdio.h&gt;  /* fclose, fopen, printf.*/
    #include &lt;stdlib.h&gt; /* 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 &lt;executable file name&gt; &lt;core file name&gt; 
</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 &lt;existing file or directory&gt; &lt;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 &lt;/dev/partitionName&gt;

       <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 &copy; 1998, Tom Bryant <BR> 
Published in Issue 29 of <i>Linux Gazette</i>, June 1998</H5></center>

<!--===================================================================-->
<P> <hr> <P> 
<A HREF="./lg_toc29.html"><IMG ALIGN=BOTTOM SRC="../gx/indexnew.gif" 
ALT="[ TABLE OF CONTENTS ]"></A>
<A HREF="../lg_frontpage.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 ============================================================-->