~ubuntu-branches/ubuntu/natty/abs-guide/natty

« back to all changes in this revision

Viewing changes to abs/HTML/gotchas.html

  • Committer: Bazaar Package Importer
  • Author(s): Sandro Tosi
  • Date: 2010-05-09 17:49:52 UTC
  • mfrom: (1.2.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20100509174952-1s583w0zbh7rl1po
Tags: 6.2-1
* New upstream release; Closes: #441278
* debian/control
  - adopting package; Closes: #577181
  - removed bzip2 from b-d-i, no more needed
  - debhelper has to be in b-d
  - bump Standards-Version to 3.8.4 (no changes needed)
  - added Homepage field
  - added misc:Depends to Depends
  - added Vcs-{Browser, Git} field
* debian/rules
  - removed the unpacking stuff, we now use an alrqady unpacked source
  - added more example scripts to fix
* debian/{compat, control, rules}
  - switched to debhelper 7
* debian/watch
  - updated to new upstream location; thanks to Raphael Geissert for the
    report; Closes: #453596
* debian/copyright
  - updated with new location and copyright/license notices
* debian/source/format
  - set source package format to 1.0 explicitly
* debian/abs-guide.doc-base
  - set Section field correctly
* debian/{copyright, abs-guide.doc-base}
  - updated upstream email
* debian/abs-guide.lintian-overrides
  - added override for "known syntax-errored" scripts

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 
2
<HTML
 
3
><HEAD
 
4
><TITLE
 
5
>Gotchas</TITLE
 
6
><META
 
7
NAME="GENERATOR"
 
8
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
 
9
"><LINK
 
10
REL="HOME"
 
11
TITLE="Advanced Bash-Scripting Guide"
 
12
HREF="index.html"><LINK
 
13
REL="UP"
 
14
TITLE="Advanced Topics"
 
15
HREF="part5.html"><LINK
 
16
REL="PREVIOUS"
 
17
TITLE="Options"
 
18
HREF="options.html"><LINK
 
19
REL="NEXT"
 
20
TITLE="Scripting With Style"
 
21
HREF="scrstyle.html"><META
 
22
HTTP-EQUIV="Content-Style-Type"
 
23
CONTENT="text/css"><LINK
 
24
REL="stylesheet"
 
25
HREF="common/kde-common.css"
 
26
TYPE="text/css"><META
 
27
HTTP-EQUIV="Content-Type"
 
28
CONTENT="text/html; charset=iso-8859-1"><META
 
29
HTTP-EQUIV="Content-Language"
 
30
CONTENT="en"><LINK
 
31
REL="stylesheet"
 
32
HREF="common/kde-localised.css"
 
33
TYPE="text/css"
 
34
TITLE="KDE-English"><LINK
 
35
REL="stylesheet"
 
36
HREF="common/kde-default.css"
 
37
TYPE="text/css"
 
38
TITLE="KDE-Default"></HEAD
 
39
><BODY
 
40
CLASS="CHAPTER"
 
41
BGCOLOR="#FFFFFF"
 
42
TEXT="#000000"
 
43
LINK="#AA0000"
 
44
VLINK="#AA0055"
 
45
ALINK="#AA0000"
 
46
STYLE="font-family: sans-serif;"
 
47
><DIV
 
48
CLASS="NAVHEADER"
 
49
><TABLE
 
50
SUMMARY="Header navigation table"
 
51
WIDTH="100%"
 
52
BORDER="0"
 
53
CELLPADDING="0"
 
54
CELLSPACING="0"
 
55
><TR
 
56
><TH
 
57
COLSPAN="3"
 
58
ALIGN="center"
 
59
>Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting</TH
 
60
></TR
 
61
><TR
 
62
><TD
 
63
WIDTH="10%"
 
64
ALIGN="left"
 
65
VALIGN="bottom"
 
66
><A
 
67
HREF="options.html"
 
68
ACCESSKEY="P"
 
69
>Prev</A
 
70
></TD
 
71
><TD
 
72
WIDTH="80%"
 
73
ALIGN="center"
 
74
VALIGN="bottom"
 
75
></TD
 
76
><TD
 
77
WIDTH="10%"
 
78
ALIGN="right"
 
79
VALIGN="bottom"
 
80
><A
 
81
HREF="scrstyle.html"
 
82
ACCESSKEY="N"
 
83
>Next</A
 
84
></TD
 
85
></TR
 
86
></TABLE
 
87
><HR
 
88
ALIGN="LEFT"
 
89
WIDTH="100%"></DIV
 
90
><DIV
 
91
CLASS="CHAPTER"
 
92
><H1
 
93
><A
 
94
NAME="GOTCHAS"
 
95
></A
 
96
>Chapter 33. Gotchas</H1
 
97
><TABLE
 
98
BORDER="0"
 
99
WIDTH="100%"
 
100
CELLSPACING="0"
 
101
CELLPADDING="0"
 
102
CLASS="EPIGRAPH"
 
103
><TR
 
104
><TD
 
105
WIDTH="45%"
 
106
>&nbsp;</TD
 
107
><TD
 
108
WIDTH="45%"
 
109
ALIGN="LEFT"
 
110
VALIGN="TOP"
 
111
><I
 
112
><P
 
113
><I
 
114
>Turandot: <I
 
115
CLASS="FOREIGNPHRASE"
 
116
>Gli enigmi sono tre, la morte
 
117
        una!</I
 
118
></I
 
119
></P
 
120
><P
 
121
><I
 
122
>Caleph: <I
 
123
CLASS="FOREIGNPHRASE"
 
124
>No, no! Gli enigmi sono tre, una la
 
125
        vita!</I
 
126
></I
 
127
></P
 
128
><P
 
129
><I
 
130
>--Puccini</I
 
131
></P
 
132
></I
 
133
></TD
 
134
></TR
 
135
></TABLE
 
136
><P
 
137
><A
 
138
NAME="BASH3GOTCHA"
 
139
></A
 
140
></P
 
141
><P
 
142
>Here are some (non-recommended!) scripting practices that
 
143
        will bring excitement into an otherwise dull life.</P
 
144
><UL
 
145
><LI
 
146
><P
 
147
><A
 
148
NAME="INAPPVN"
 
149
></A
 
150
></P
 
151
><P
 
152
>Assigning reserved words or characters to variable names.</P
 
153
><P
 
154
>       <TABLE
 
155
BORDER="0"
 
156
BGCOLOR="#E0E0E0"
 
157
WIDTH="90%"
 
158
><TR
 
159
><TD
 
160
><PRE
 
161
CLASS="PROGRAMLISTING"
 
162
>   1&nbsp;case=value0       # Causes problems.
 
163
   2&nbsp;23skidoo=value1   # Also problems.
 
164
   3&nbsp;# Variable names starting with a digit are reserved by the shell.
 
165
   4&nbsp;# Try _23skidoo=value1. Starting variables with an underscore is okay.
 
166
   5&nbsp;
 
167
   6&nbsp;# However . . .   using just an underscore will not work.
 
168
   7&nbsp;_=25
 
169
   8&nbsp;echo $_           # $_ is a special variable set to last arg of last command.
 
170
   9&nbsp;# But . . .       _ is a valid function name!
 
171
  10&nbsp;
 
172
  11&nbsp;xyz((!*=value2    # Causes severe problems.
 
173
  12&nbsp;# As of version 3 of Bash, periods are not allowed within variable names.</PRE
 
174
></TD
 
175
></TR
 
176
></TABLE
 
177
>
 
178
        </P
 
179
></LI
 
180
><LI
 
181
><P
 
182
>Using a hyphen or other reserved characters in a variable name (or
 
183
        function name).</P
 
184
><P
 
185
>       <TABLE
 
186
BORDER="0"
 
187
BGCOLOR="#E0E0E0"
 
188
WIDTH="90%"
 
189
><TR
 
190
><TD
 
191
><PRE
 
192
CLASS="PROGRAMLISTING"
 
193
>   1&nbsp;var-1=23
 
194
   2&nbsp;# Use 'var_1' instead.
 
195
   3&nbsp;
 
196
   4&nbsp;function-whatever ()   # Error
 
197
   5&nbsp;# Use 'function_whatever ()' instead.
 
198
   6&nbsp;
 
199
   7&nbsp; 
 
200
   8&nbsp;# As of version 3 of Bash, periods are not allowed within function names.
 
201
   9&nbsp;function.whatever ()   # Error
 
202
  10&nbsp;# Use 'functionWhatever ()' instead.</PRE
 
203
></TD
 
204
></TR
 
205
></TABLE
 
206
>
 
207
      </P
 
208
></LI
 
209
><LI
 
210
><P
 
211
>Using the same name for a variable and a function. This can make a
 
212
        script difficult to understand.</P
 
213
><P
 
214
>        <TABLE
 
215
BORDER="0"
 
216
BGCOLOR="#E0E0E0"
 
217
WIDTH="90%"
 
218
><TR
 
219
><TD
 
220
><PRE
 
221
CLASS="PROGRAMLISTING"
 
222
>   1&nbsp;do_something ()
 
223
   2&nbsp;{
 
224
   3&nbsp;  echo "This function does something with \"$1\"."
 
225
   4&nbsp;}
 
226
   5&nbsp;
 
227
   6&nbsp;do_something=do_something
 
228
   7&nbsp;
 
229
   8&nbsp;do_something do_something
 
230
   9&nbsp;
 
231
  10&nbsp;# All this is legal, but highly confusing.</PRE
 
232
></TD
 
233
></TR
 
234
></TABLE
 
235
>
 
236
        </P
 
237
></LI
 
238
><LI
 
239
><P
 
240
><A
 
241
NAME="WSBAD"
 
242
></A
 
243
>Using <A
 
244
HREF="special-chars.html#WHITESPACEREF"
 
245
>whitespace</A
 
246
> inappropriately.
 
247
        In contrast to other programming languages, Bash can be quite
 
248
        finicky about whitespace.</P
 
249
><P
 
250
>       <TABLE
 
251
BORDER="0"
 
252
BGCOLOR="#E0E0E0"
 
253
WIDTH="90%"
 
254
><TR
 
255
><TD
 
256
><PRE
 
257
CLASS="PROGRAMLISTING"
 
258
>   1&nbsp;var1 = 23   # 'var1=23' is correct.
 
259
   2&nbsp;# On line above, Bash attempts to execute command "var1"
 
260
   3&nbsp;# with the arguments "=" and "23".
 
261
   4&nbsp;      
 
262
   5&nbsp;let c = $a - $b   # Instead:   let c=$a-$b   or   let "c = $a - $b"
 
263
   6&nbsp;
 
264
   7&nbsp;if [ $a -le 5]    # if [ $a -le 5 ]   is correct.
 
265
   8&nbsp;#           ^^      if [ "$a" -le 5 ]   is even better.
 
266
   9&nbsp;                  # [[ $a -le 5 ]] also works.</PRE
 
267
></TD
 
268
></TR
 
269
></TABLE
 
270
>
 
271
        </P
 
272
></LI
 
273
><LI
 
274
><P
 
275
><A
 
276
NAME="OMITSEMICOLON"
 
277
></A
 
278
></P
 
279
><P
 
280
>Not terminating with a <A
 
281
HREF="special-chars.html#SEMICOLONREF"
 
282
>semicolon</A
 
283
> the final command
 
284
        in a <A
 
285
HREF="special-chars.html#CODEBLOCKREF"
 
286
>code block within curly
 
287
        brackets</A
 
288
>.</P
 
289
><P
 
290
>        <TABLE
 
291
BORDER="0"
 
292
BGCOLOR="#E0E0E0"
 
293
WIDTH="90%"
 
294
><TR
 
295
><TD
 
296
><PRE
 
297
CLASS="PROGRAMLISTING"
 
298
>   1&nbsp;{ ls -l; df; echo "Done." }
 
299
   2&nbsp;# bash: syntax error: unexpected end of file
 
300
   3&nbsp;
 
301
   4&nbsp;{ ls -l; df; echo "Done."; }
 
302
   5&nbsp;#                        ^     ### Final command needs semicolon.</PRE
 
303
></TD
 
304
></TR
 
305
></TABLE
 
306
>
 
307
      </P
 
308
></LI
 
309
><LI
 
310
><P
 
311
><A
 
312
NAME="UNINITVAR"
 
313
></A
 
314
></P
 
315
><P
 
316
>        Assuming uninitialized variables (variables before a value is
 
317
        assigned to them) are <SPAN
 
318
CLASS="QUOTE"
 
319
>"zeroed out"</SPAN
 
320
>. An
 
321
        uninitialized variable has a value of <I
 
322
CLASS="FIRSTTERM"
 
323
>null</I
 
324
>,
 
325
        <SPAN
 
326
CLASS="emphasis"
 
327
><I
 
328
CLASS="EMPHASIS"
 
329
>not</I
 
330
></SPAN
 
331
> zero.</P
 
332
><P
 
333
>          <TABLE
 
334
BORDER="0"
 
335
BGCOLOR="#E0E0E0"
 
336
WIDTH="90%"
 
337
><TR
 
338
><TD
 
339
><PRE
 
340
CLASS="PROGRAMLISTING"
 
341
>   1&nbsp;#!/bin/bash
 
342
   2&nbsp;
 
343
   3&nbsp;echo "uninitialized_var = $uninitialized_var"
 
344
   4&nbsp;# uninitialized_var =</PRE
 
345
></TD
 
346
></TR
 
347
></TABLE
 
348
>
 
349
 
 
350
      </P
 
351
></LI
 
352
><LI
 
353
><P
 
354
><A
 
355
NAME="EQDIF"
 
356
></A
 
357
></P
 
358
><P
 
359
>Mixing up <I
 
360
CLASS="FIRSTTERM"
 
361
>=</I
 
362
> and
 
363
          <I
 
364
CLASS="FIRSTTERM"
 
365
>-eq</I
 
366
> in a test. Remember,
 
367
          <I
 
368
CLASS="FIRSTTERM"
 
369
>=</I
 
370
> is for comparing literal variables
 
371
          and <I
 
372
CLASS="FIRSTTERM"
 
373
>-eq</I
 
374
> for integers.</P
 
375
><P
 
376
>       <TABLE
 
377
BORDER="0"
 
378
BGCOLOR="#E0E0E0"
 
379
WIDTH="90%"
 
380
><TR
 
381
><TD
 
382
><PRE
 
383
CLASS="PROGRAMLISTING"
 
384
>   1&nbsp;if [ "$a" = 273 ]      # Is $a an integer or string?
 
385
   2&nbsp;if [ "$a" -eq 273 ]    # If $a is an integer.
 
386
   3&nbsp;
 
387
   4&nbsp;# Sometimes you can interchange -eq and = without adverse consequences.
 
388
   5&nbsp;# However . . .
 
389
   6&nbsp;
 
390
   7&nbsp;
 
391
   8&nbsp;a=273.0   # Not an integer.
 
392
   9&nbsp;         
 
393
  10&nbsp;if [ "$a" = 273 ]
 
394
  11&nbsp;then
 
395
  12&nbsp;  echo "Comparison works."
 
396
  13&nbsp;else  
 
397
  14&nbsp;  echo "Comparison does not work."
 
398
  15&nbsp;fi    # Comparison does not work.
 
399
  16&nbsp;
 
400
  17&nbsp;# Same with   a=" 273"  and a="0273".
 
401
  18&nbsp;
 
402
  19&nbsp;
 
403
  20&nbsp;# Likewise, problems trying to use "-eq" with non-integer values.
 
404
  21&nbsp;         
 
405
  22&nbsp;if [ "$a" -eq 273.0 ]
 
406
  23&nbsp;then
 
407
  24&nbsp;  echo "a = $a"
 
408
  25&nbsp;fi  # Aborts with an error message.  
 
409
  26&nbsp;# test.sh: [: 273.0: integer expression expected</PRE
 
410
></TD
 
411
></TR
 
412
></TABLE
 
413
>
 
414
        </P
 
415
></LI
 
416
><LI
 
417
><P
 
418
><A
 
419
NAME="NUMSTRCOMPNE"
 
420
></A
 
421
></P
 
422
><P
 
423
>Misusing <A
 
424
HREF="comparison-ops.html#SCOMPARISON1"
 
425
>string comparison</A
 
426
>
 
427
        operators.</P
 
428
><DIV
 
429
CLASS="EXAMPLE"
 
430
><HR><A
 
431
NAME="BADOP"
 
432
></A
 
433
><P
 
434
><B
 
435
>Example 33-1. Numerical and string comparison are not equivalent</B
 
436
></P
 
437
><TABLE
 
438
BORDER="0"
 
439
BGCOLOR="#E0E0E0"
 
440
WIDTH="90%"
 
441
><TR
 
442
><TD
 
443
><PRE
 
444
CLASS="PROGRAMLISTING"
 
445
>   1&nbsp;#!/bin/bash
 
446
   2&nbsp;# bad-op.sh: Trying to use a string comparison on integers.
 
447
   3&nbsp;
 
448
   4&nbsp;echo
 
449
   5&nbsp;number=1
 
450
   6&nbsp;
 
451
   7&nbsp;#  The following while-loop has two errors:
 
452
   8&nbsp;#+ one blatant, and the other subtle.
 
453
   9&nbsp;
 
454
  10&nbsp;while [ "$number" &#60; 5 ]    # Wrong! Should be:  while [ "$number" -lt 5 ]
 
455
  11&nbsp;do
 
456
  12&nbsp;  echo -n "$number "
 
457
  13&nbsp;  let "number += 1"
 
458
  14&nbsp;done  
 
459
  15&nbsp;#  Attempt to run this bombs with the error message:
 
460
  16&nbsp;#+ bad-op.sh: line 10: 5: No such file or directory
 
461
  17&nbsp;#  Within single brackets, "&#60;" must be escaped,
 
462
  18&nbsp;#+ and even then, it's still wrong for comparing integers.
 
463
  19&nbsp;
 
464
  20&nbsp;echo "---------------------"
 
465
  21&nbsp;
 
466
  22&nbsp;while [ "$number" \&#60; 5 ]    #  1 2 3 4
 
467
  23&nbsp;do                          #
 
468
  24&nbsp;  echo -n "$number "        #  It *seems* to work, but . . .
 
469
  25&nbsp;  let "number += 1"         #+ it actually does an ASCII comparison,
 
470
  26&nbsp;done                        #+ rather than a numerical one.
 
471
  27&nbsp;
 
472
  28&nbsp;echo; echo "---------------------"
 
473
  29&nbsp;
 
474
  30&nbsp;# This can cause problems. For example:
 
475
  31&nbsp;
 
476
  32&nbsp;lesser=5
 
477
  33&nbsp;greater=105
 
478
  34&nbsp;
 
479
  35&nbsp;if [ "$greater" \&#60; "$lesser" ]
 
480
  36&nbsp;then
 
481
  37&nbsp;  echo "$greater is less than $lesser"
 
482
  38&nbsp;fi                          # 105 is less than 5
 
483
  39&nbsp;#  In fact, "105" actually is less than "5"
 
484
  40&nbsp;#+ in a string comparison (ASCII sort order).
 
485
  41&nbsp;
 
486
  42&nbsp;echo
 
487
  43&nbsp;
 
488
  44&nbsp;exit 0</PRE
 
489
></TD
 
490
></TR
 
491
></TABLE
 
492
><HR></DIV
 
493
></LI
 
494
><LI
 
495
><P
 
496
><A
 
497
NAME="LETBAD"
 
498
></A
 
499
></P
 
500
><P
 
501
>Attempting to use <A
 
502
HREF="internal.html#LETREF"
 
503
>let</A
 
504
>
 
505
                to set string variables.</P
 
506
><P
 
507
><TABLE
 
508
BORDER="0"
 
509
BGCOLOR="#E0E0E0"
 
510
WIDTH="90%"
 
511
><TR
 
512
><TD
 
513
><PRE
 
514
CLASS="PROGRAMLISTING"
 
515
>   1&nbsp;let "a = hello, you"
 
516
   2&nbsp;echo "$a"   # 0</PRE
 
517
></TD
 
518
></TR
 
519
></TABLE
 
520
></P
 
521
></LI
 
522
><LI
 
523
><P
 
524
><A
 
525
NAME="FAILQUOTE"
 
526
></A
 
527
></P
 
528
><P
 
529
>Sometimes variables within <SPAN
 
530
CLASS="QUOTE"
 
531
>"test"</SPAN
 
532
> brackets
 
533
        ([ ]) need to be quoted (double quotes).  Failure to do so may
 
534
        cause unexpected behavior. See <A
 
535
HREF="comparison-ops.html#STRTEST"
 
536
>Example 7-6</A
 
537
>, <A
 
538
HREF="redircb.html#REDIR2"
 
539
>Example 20-5</A
 
540
>, and <A
 
541
HREF="variables2.html#ARGLIST"
 
542
>Example 9-6</A
 
543
>.</P
 
544
></LI
 
545
><LI
 
546
><P
 
547
><A
 
548
NAME="FAILNOTQUOTE"
 
549
></A
 
550
></P
 
551
><P
 
552
>Quoting a variable containing whitespace <A
 
553
HREF="quoting.html#WSQUO"
 
554
>prevents splitting</A
 
555
>. Sometimes
 
556
        this produces <A
 
557
HREF="quoting.html#VARSPLITTING"
 
558
>unintended
 
559
        consequences</A
 
560
>.</P
 
561
></LI
 
562
><LI
 
563
><P
 
564
><A
 
565
NAME="EXECPERM"
 
566
></A
 
567
></P
 
568
><P
 
569
>Commands issued from a script may fail to execute because
 
570
        the script owner lacks execute permission for them. If a user
 
571
        cannot invoke a command from the command-line, then putting it
 
572
        into a script will likewise fail. Try changing the attributes of
 
573
        the command in question, perhaps even setting the suid bit
 
574
        (as <I
 
575
CLASS="FIRSTTERM"
 
576
>root</I
 
577
>, of course).</P
 
578
></LI
 
579
><LI
 
580
><P
 
581
><A
 
582
NAME="DASHNREDR"
 
583
></A
 
584
></P
 
585
><P
 
586
>Attempting to use <B
 
587
CLASS="COMMAND"
 
588
>-</B
 
589
> as a redirection
 
590
        operator (which it is not) will usually result in an unpleasant
 
591
        surprise.</P
 
592
><P
 
593
>       <TABLE
 
594
BORDER="0"
 
595
BGCOLOR="#E0E0E0"
 
596
WIDTH="90%"
 
597
><TR
 
598
><TD
 
599
><PRE
 
600
CLASS="PROGRAMLISTING"
 
601
>   1&nbsp;command1 2&#62; - | command2
 
602
   2&nbsp;# Trying to redirect error output of command1 into a pipe . . .
 
603
   3&nbsp;# . . . will not work.        
 
604
   4&nbsp;
 
605
   5&nbsp;command1 2&#62;&#38; - | command2  # Also futile.
 
606
   6&nbsp;
 
607
   7&nbsp;Thanks, S.C.</PRE
 
608
></TD
 
609
></TR
 
610
></TABLE
 
611
></P
 
612
></LI
 
613
><LI
 
614
><P
 
615
><A
 
616
NAME="LATEVERF"
 
617
></A
 
618
></P
 
619
><P
 
620
>Using Bash <A
 
621
HREF="bash2.html#BASH2REF"
 
622
>version 2+</A
 
623
>
 
624
        functionality may cause a bailout with error messages. Older
 
625
        Linux machines may have version 1.XX of Bash as the default
 
626
        installation.</P
 
627
><P
 
628
>       <TABLE
 
629
BORDER="0"
 
630
BGCOLOR="#E0E0E0"
 
631
WIDTH="90%"
 
632
><TR
 
633
><TD
 
634
><PRE
 
635
CLASS="PROGRAMLISTING"
 
636
>   1&nbsp;#!/bin/bash
 
637
   2&nbsp;
 
638
   3&nbsp;minimum_version=2
 
639
   4&nbsp;# Since Chet Ramey is constantly adding features to Bash,
 
640
   5&nbsp;# you may set $minimum_version to 2.XX, 3.XX, or whatever is appropriate.
 
641
   6&nbsp;E_BAD_VERSION=80
 
642
   7&nbsp;
 
643
   8&nbsp;if [ "$BASH_VERSION" \&#60; "$minimum_version" ]
 
644
   9&nbsp;then
 
645
  10&nbsp;  echo "This script works only with Bash, version $minimum or greater."
 
646
  11&nbsp;  echo "Upgrade strongly recommended."
 
647
  12&nbsp;  exit $E_BAD_VERSION
 
648
  13&nbsp;fi
 
649
  14&nbsp;
 
650
  15&nbsp;...</PRE
 
651
></TD
 
652
></TR
 
653
></TABLE
 
654
></P
 
655
></LI
 
656
><LI
 
657
><P
 
658
>Using Bash-specific functionality in a <A
 
659
HREF="why-shell.html#BASHDEF"
 
660
>Bourne shell</A
 
661
> script
 
662
        (<TT
 
663
CLASS="USERINPUT"
 
664
><B
 
665
>#!/bin/sh</B
 
666
></TT
 
667
>) on a non-Linux machine
 
668
        <A
 
669
HREF="gotchas.html#BINSH"
 
670
>may cause unexpected behavior</A
 
671
>.
 
672
        A Linux system usually aliases <B
 
673
CLASS="COMMAND"
 
674
>sh</B
 
675
> to
 
676
        <B
 
677
CLASS="COMMAND"
 
678
>bash</B
 
679
>, but this does not necessarily hold true
 
680
        for a generic UNIX machine.</P
 
681
></LI
 
682
><LI
 
683
><P
 
684
><A
 
685
NAME="UNDOCF"
 
686
></A
 
687
></P
 
688
><P
 
689
>Using undocumented features in Bash turns out to be a
 
690
        dangerous practice. In previous releases of this
 
691
        book there were several scripts that depended on the
 
692
        <SPAN
 
693
CLASS="QUOTE"
 
694
>"feature"</SPAN
 
695
> that, although the maximum value
 
696
        of an <A
 
697
HREF="exit-status.html#EXITSTATUSREF"
 
698
>exit</A
 
699
> or <A
 
700
HREF="functions.html#RETURNREF"
 
701
>return</A
 
702
> value was 255, that limit
 
703
        did not apply to <SPAN
 
704
CLASS="emphasis"
 
705
><I
 
706
CLASS="EMPHASIS"
 
707
>negative</I
 
708
></SPAN
 
709
> integers.
 
710
        Unfortunately, in version 2.05b and later, that loophole
 
711
        disappeared.  See <A
 
712
HREF="functions.html#RETURNTEST"
 
713
>Example 24-9</A
 
714
>.</P
 
715
></LI
 
716
><LI
 
717
><P
 
718
><A
 
719
NAME="DOSNEWLINES"
 
720
></A
 
721
></P
 
722
><P
 
723
>        A script with DOS-type newlines (<TT
 
724
CLASS="REPLACEABLE"
 
725
><I
 
726
>\r\n</I
 
727
></TT
 
728
>)
 
729
        will fail to execute, since <TT
 
730
CLASS="USERINPUT"
 
731
><B
 
732
>#!/bin/bash\r\n</B
 
733
></TT
 
734
>
 
735
        is <SPAN
 
736
CLASS="emphasis"
 
737
><I
 
738
CLASS="EMPHASIS"
 
739
>not</I
 
740
></SPAN
 
741
> recognized, <SPAN
 
742
CLASS="emphasis"
 
743
><I
 
744
CLASS="EMPHASIS"
 
745
>not</I
 
746
></SPAN
 
747
>
 
748
        the same as the expected <TT
 
749
CLASS="USERINPUT"
 
750
><B
 
751
>#!/bin/bash\n</B
 
752
></TT
 
753
>. The
 
754
        fix is to convert the script to UNIX-style newlines.</P
 
755
><P
 
756
>         <TABLE
 
757
BORDER="0"
 
758
BGCOLOR="#E0E0E0"
 
759
WIDTH="90%"
 
760
><TR
 
761
><TD
 
762
><PRE
 
763
CLASS="PROGRAMLISTING"
 
764
>   1&nbsp;#!/bin/bash
 
765
   2&nbsp;
 
766
   3&nbsp;echo "Here"
 
767
   4&nbsp;
 
768
   5&nbsp;unix2dos $0    # Script changes itself to DOS format.
 
769
   6&nbsp;chmod 755 $0   # Change back to execute permission.
 
770
   7&nbsp;               # The 'unix2dos' command removes execute permission.
 
771
   8&nbsp;
 
772
   9&nbsp;./$0           # Script tries to run itself again.
 
773
  10&nbsp;               # But it won't work as a DOS file.
 
774
  11&nbsp;
 
775
  12&nbsp;echo "There"
 
776
  13&nbsp;
 
777
  14&nbsp;exit 0</PRE
 
778
></TD
 
779
></TR
 
780
></TABLE
 
781
>
 
782
      </P
 
783
></LI
 
784
><LI
 
785
><P
 
786
><A
 
787
NAME="BINSH"
 
788
></A
 
789
></P
 
790
><P
 
791
>A shell script headed by <TT
 
792
CLASS="USERINPUT"
 
793
><B
 
794
>#!/bin/sh</B
 
795
></TT
 
796
>
 
797
        will not run in full Bash-compatibility mode. Some Bash-specific
 
798
        functions might be disabled. Scripts that need complete
 
799
        access to all the Bash-specific extensions should start with
 
800
        <TT
 
801
CLASS="USERINPUT"
 
802
><B
 
803
>#!/bin/bash</B
 
804
></TT
 
805
>.</P
 
806
></LI
 
807
><LI
 
808
><P
 
809
><A
 
810
HREF="here-docs.html#INDENTEDLS"
 
811
>Putting whitespace in front of
 
812
        the terminating limit string</A
 
813
> of a <A
 
814
HREF="here-docs.html#HEREDOCREF"
 
815
>here document</A
 
816
> will cause unexpected
 
817
        behavior in a script.</P
 
818
></LI
 
819
><LI
 
820
><P
 
821
><A
 
822
NAME="RVTCAUTION2"
 
823
></A
 
824
>Putting more than one
 
825
        <I
 
826
CLASS="FIRSTTERM"
 
827
>echo</I
 
828
> statement in a function <A
 
829
HREF="assortedtips.html#RVT"
 
830
>whose output is captured</A
 
831
>.
 
832
        <TABLE
 
833
BORDER="0"
 
834
BGCOLOR="#E0E0E0"
 
835
WIDTH="90%"
 
836
><TR
 
837
><TD
 
838
><PRE
 
839
CLASS="PROGRAMLISTING"
 
840
>   1&nbsp;add2 ()
 
841
   2&nbsp;{
 
842
   3&nbsp;  echo "Whatever ... "   # Delete this line!
 
843
   4&nbsp;  let "retval = $1 + $2"
 
844
   5&nbsp;    echo $retval
 
845
   6&nbsp;    }
 
846
   7&nbsp;
 
847
   8&nbsp;    num1=12
 
848
   9&nbsp;    num2=43
 
849
  10&nbsp;    echo "Sum of $num1 and $num2 = $(add2 $num1 $num2)"
 
850
  11&nbsp;
 
851
  12&nbsp;#   Sum of 12 and 43 = Whatever ... 
 
852
  13&nbsp;#   55
 
853
  14&nbsp;
 
854
  15&nbsp;#        The "echoes" concatenate.</PRE
 
855
></TD
 
856
></TR
 
857
></TABLE
 
858
>
 
859
        This <A
 
860
HREF="assortedtips.html#RVTCAUTION"
 
861
>will not work</A
 
862
>.</P
 
863
></LI
 
864
><LI
 
865
><P
 
866
><A
 
867
NAME="PARCHILDPROBREF"
 
868
></A
 
869
></P
 
870
><P
 
871
>A script may not <B
 
872
CLASS="COMMAND"
 
873
>export</B
 
874
> variables back
 
875
        to its <A
 
876
HREF="internal.html#FORKREF"
 
877
>parent process</A
 
878
>, the shell,
 
879
        or to the environment. Just as we learned in biology, a child
 
880
        process can inherit from a parent, but not vice versa.</P
 
881
><P
 
882
>         <TABLE
 
883
BORDER="0"
 
884
BGCOLOR="#E0E0E0"
 
885
WIDTH="90%"
 
886
><TR
 
887
><TD
 
888
><PRE
 
889
CLASS="PROGRAMLISTING"
 
890
>   1&nbsp;WHATEVER=/home/bozo
 
891
   2&nbsp;export WHATEVER
 
892
   3&nbsp;exit 0</PRE
 
893
></TD
 
894
></TR
 
895
></TABLE
 
896
>
 
897
          <TABLE
 
898
BORDER="0"
 
899
BGCOLOR="#E0E0E0"
 
900
WIDTH="90%"
 
901
><TR
 
902
><TD
 
903
><PRE
 
904
CLASS="SCREEN"
 
905
> <TT
 
906
CLASS="PROMPT"
 
907
>bash$ </TT
 
908
><B
 
909
CLASS="COMMAND"
 
910
>echo $WHATEVER</B
 
911
>
 
912
 <TT
 
913
CLASS="COMPUTEROUTPUT"
 
914
></TT
 
915
>
 
916
 <TT
 
917
CLASS="PROMPT"
 
918
>bash$ </TT
 
919
></PRE
 
920
></TD
 
921
></TR
 
922
></TABLE
 
923
>
 
924
      </P
 
925
><P
 
926
>        Sure enough, back at the command prompt, $WHATEVER remains unset.
 
927
       </P
 
928
></LI
 
929
><LI
 
930
><P
 
931
><A
 
932
NAME="VARSUBSH"
 
933
></A
 
934
></P
 
935
><P
 
936
>Setting and manipulating variables in a <A
 
937
HREF="subshells.html#SUBSHELLSREF"
 
938
>subshell</A
 
939
>, then attempting
 
940
        to use those same variables outside the scope of the subshell will
 
941
        result an unpleasant surprise.</P
 
942
><DIV
 
943
CLASS="EXAMPLE"
 
944
><HR><A
 
945
NAME="SUBPIT"
 
946
></A
 
947
><P
 
948
><B
 
949
>Example 33-2. Subshell Pitfalls</B
 
950
></P
 
951
><TABLE
 
952
BORDER="0"
 
953
BGCOLOR="#E0E0E0"
 
954
WIDTH="90%"
 
955
><TR
 
956
><TD
 
957
><PRE
 
958
CLASS="PROGRAMLISTING"
 
959
>   1&nbsp;#!/bin/bash
 
960
   2&nbsp;# Pitfalls of variables in a subshell.
 
961
   3&nbsp;
 
962
   4&nbsp;outer_variable=outer
 
963
   5&nbsp;echo
 
964
   6&nbsp;echo "outer_variable = $outer_variable"
 
965
   7&nbsp;echo
 
966
   8&nbsp;
 
967
   9&nbsp;(
 
968
  10&nbsp;# Begin subshell
 
969
  11&nbsp;
 
970
  12&nbsp;echo "outer_variable inside subshell = $outer_variable"
 
971
  13&nbsp;inner_variable=inner  # Set
 
972
  14&nbsp;echo "inner_variable inside subshell = $inner_variable"
 
973
  15&nbsp;outer_variable=inner  # Will value change globally?
 
974
  16&nbsp;echo "outer_variable inside subshell = $outer_variable"
 
975
  17&nbsp;
 
976
  18&nbsp;# Will 'exporting' make a difference?
 
977
  19&nbsp;#    export inner_variable
 
978
  20&nbsp;#    export outer_variable
 
979
  21&nbsp;# Try it and see.
 
980
  22&nbsp;
 
981
  23&nbsp;# End subshell
 
982
  24&nbsp;)
 
983
  25&nbsp;
 
984
  26&nbsp;echo
 
985
  27&nbsp;echo "inner_variable outside subshell = $inner_variable"  # Unset.
 
986
  28&nbsp;echo "outer_variable outside subshell = $outer_variable"  # Unchanged.
 
987
  29&nbsp;echo
 
988
  30&nbsp;
 
989
  31&nbsp;exit 0
 
990
  32&nbsp;
 
991
  33&nbsp;# What happens if you uncomment lines 19 and 20?
 
992
  34&nbsp;# Does it make a difference?</PRE
 
993
></TD
 
994
></TR
 
995
></TABLE
 
996
><HR></DIV
 
997
></LI
 
998
><LI
 
999
><P
 
1000
><A
 
1001
NAME="BADREAD0"
 
1002
></A
 
1003
></P
 
1004
><P
 
1005
><A
 
1006
HREF="special-chars.html#PIPEREF"
 
1007
>Piping</A
 
1008
>
 
1009
        <B
 
1010
CLASS="COMMAND"
 
1011
>echo</B
 
1012
> output to a <A
 
1013
HREF="internal.html#READREF"
 
1014
>read</A
 
1015
> may produce unexpected
 
1016
        results.  In this scenario, the <B
 
1017
CLASS="COMMAND"
 
1018
>read</B
 
1019
>
 
1020
        acts as if it were running in a subshell. Instead, use
 
1021
        the <A
 
1022
HREF="internal.html#SETREF"
 
1023
>set</A
 
1024
> command (as in <A
 
1025
HREF="internal.html#SETPOS"
 
1026
>Example 15-18</A
 
1027
>).</P
 
1028
><DIV
 
1029
CLASS="EXAMPLE"
 
1030
><HR><A
 
1031
NAME="BADREAD"
 
1032
></A
 
1033
><P
 
1034
><B
 
1035
>Example 33-3. Piping the output of <I
 
1036
CLASS="FIRSTTERM"
 
1037
>echo</I
 
1038
> to a
 
1039
        <I
 
1040
CLASS="FIRSTTERM"
 
1041
>read</I
 
1042
></B
 
1043
></P
 
1044
><TABLE
 
1045
BORDER="0"
 
1046
BGCOLOR="#E0E0E0"
 
1047
WIDTH="90%"
 
1048
><TR
 
1049
><TD
 
1050
><PRE
 
1051
CLASS="PROGRAMLISTING"
 
1052
>   1&nbsp;#!/bin/bash
 
1053
   2&nbsp;#  badread.sh:
 
1054
   3&nbsp;#  Attempting to use 'echo and 'read'
 
1055
   4&nbsp;#+ to assign variables non-interactively.
 
1056
   5&nbsp;
 
1057
   6&nbsp;a=aaa
 
1058
   7&nbsp;b=bbb
 
1059
   8&nbsp;c=ccc
 
1060
   9&nbsp;
 
1061
  10&nbsp;echo "one two three" | read a b c
 
1062
  11&nbsp;# Try to reassign a, b, and c.
 
1063
  12&nbsp;
 
1064
  13&nbsp;echo
 
1065
  14&nbsp;echo "a = $a"  # a = aaa
 
1066
  15&nbsp;echo "b = $b"  # b = bbb
 
1067
  16&nbsp;echo "c = $c"  # c = ccc
 
1068
  17&nbsp;# Reassignment failed.
 
1069
  18&nbsp;
 
1070
  19&nbsp;# ------------------------------
 
1071
  20&nbsp;
 
1072
  21&nbsp;# Try the following alternative.
 
1073
  22&nbsp;
 
1074
  23&nbsp;var=`echo "one two three"`
 
1075
  24&nbsp;set -- $var
 
1076
  25&nbsp;a=$1; b=$2; c=$3
 
1077
  26&nbsp;
 
1078
  27&nbsp;echo "-------"
 
1079
  28&nbsp;echo "a = $a"  # a = one
 
1080
  29&nbsp;echo "b = $b"  # b = two
 
1081
  30&nbsp;echo "c = $c"  # c = three 
 
1082
  31&nbsp;# Reassignment succeeded.
 
1083
  32&nbsp;
 
1084
  33&nbsp;# ------------------------------
 
1085
  34&nbsp;
 
1086
  35&nbsp;#  Note also that an echo to a 'read' works within a subshell.
 
1087
  36&nbsp;#  However, the value of the variable changes *only* within the subshell.
 
1088
  37&nbsp;
 
1089
  38&nbsp;a=aaa          # Starting all over again.
 
1090
  39&nbsp;b=bbb
 
1091
  40&nbsp;c=ccc
 
1092
  41&nbsp;
 
1093
  42&nbsp;echo; echo
 
1094
  43&nbsp;echo "one two three" | ( read a b c;
 
1095
  44&nbsp;echo "Inside subshell: "; echo "a = $a"; echo "b = $b"; echo "c = $c" )
 
1096
  45&nbsp;# a = one
 
1097
  46&nbsp;# b = two
 
1098
  47&nbsp;# c = three
 
1099
  48&nbsp;echo "-----------------"
 
1100
  49&nbsp;echo "Outside subshell: "
 
1101
  50&nbsp;echo "a = $a"  # a = aaa
 
1102
  51&nbsp;echo "b = $b"  # b = bbb
 
1103
  52&nbsp;echo "c = $c"  # c = ccc
 
1104
  53&nbsp;echo
 
1105
  54&nbsp;
 
1106
  55&nbsp;exit 0</PRE
 
1107
></TD
 
1108
></TR
 
1109
></TABLE
 
1110
><HR></DIV
 
1111
><P
 
1112
><A
 
1113
NAME="PIPELOOP"
 
1114
></A
 
1115
></P
 
1116
><P
 
1117
>In fact, as Anthony Richardson points out, piping to
 
1118
        <SPAN
 
1119
CLASS="emphasis"
 
1120
><I
 
1121
CLASS="EMPHASIS"
 
1122
>any</I
 
1123
></SPAN
 
1124
> loop can cause a similar problem.</P
 
1125
><P
 
1126
>       
 
1127
<TABLE
 
1128
BORDER="0"
 
1129
BGCOLOR="#E0E0E0"
 
1130
WIDTH="90%"
 
1131
><TR
 
1132
><TD
 
1133
><PRE
 
1134
CLASS="PROGRAMLISTING"
 
1135
>   1&nbsp;# Loop piping troubles.
 
1136
   2&nbsp;#  This example by Anthony Richardson,
 
1137
   3&nbsp;#+ with addendum by Wilbert Berendsen.
 
1138
   4&nbsp;
 
1139
   5&nbsp;
 
1140
   6&nbsp;foundone=false
 
1141
   7&nbsp;find $HOME -type f -atime +30 -size 100k |
 
1142
   8&nbsp;while true
 
1143
   9&nbsp;do
 
1144
  10&nbsp;   read f
 
1145
  11&nbsp;   echo "$f is over 100KB and has not been accessed in over 30 days"
 
1146
  12&nbsp;   echo "Consider moving the file to archives."
 
1147
  13&nbsp;   foundone=true
 
1148
  14&nbsp;   # ------------------------------------
 
1149
  15&nbsp;   echo "Subshell level = $BASH_SUBSHELL"
 
1150
  16&nbsp;   # Subshell level = 1
 
1151
  17&nbsp;   # Yes, we're inside a subshell.
 
1152
  18&nbsp;   # ------------------------------------
 
1153
  19&nbsp;done
 
1154
  20&nbsp;   
 
1155
  21&nbsp;#  foundone will always be false here since it is
 
1156
  22&nbsp;#+ set to true inside a subshell
 
1157
  23&nbsp;if [ $foundone = false ]
 
1158
  24&nbsp;then
 
1159
  25&nbsp;   echo "No files need archiving."
 
1160
  26&nbsp;fi
 
1161
  27&nbsp;
 
1162
  28&nbsp;# =====================Now, here is the correct way:=================
 
1163
  29&nbsp;
 
1164
  30&nbsp;foundone=false
 
1165
  31&nbsp;for f in $(find $HOME -type f -atime +30 -size 100k)  # No pipe here.
 
1166
  32&nbsp;do
 
1167
  33&nbsp;   echo "$f is over 100KB and has not been accessed in over 30 days"
 
1168
  34&nbsp;   echo "Consider moving the file to archives."
 
1169
  35&nbsp;   foundone=true
 
1170
  36&nbsp;done
 
1171
  37&nbsp;   
 
1172
  38&nbsp;if [ $foundone = false ]
 
1173
  39&nbsp;then
 
1174
  40&nbsp;   echo "No files need archiving."
 
1175
  41&nbsp;fi
 
1176
  42&nbsp;
 
1177
  43&nbsp;# ==================And here is another alternative==================
 
1178
  44&nbsp;
 
1179
  45&nbsp;#  Places the part of the script that reads the variables
 
1180
  46&nbsp;#+ within a code block, so they share the same subshell.
 
1181
  47&nbsp;#  Thank you, W.B.
 
1182
  48&nbsp;
 
1183
  49&nbsp;find $HOME -type f -atime +30 -size 100k | {
 
1184
  50&nbsp;     foundone=false
 
1185
  51&nbsp;     while read f
 
1186
  52&nbsp;     do
 
1187
  53&nbsp;       echo "$f is over 100KB and has not been accessed in over 30 days"
 
1188
  54&nbsp;       echo "Consider moving the file to archives."
 
1189
  55&nbsp;       foundone=true
 
1190
  56&nbsp;     done
 
1191
  57&nbsp;
 
1192
  58&nbsp;     if ! $foundone
 
1193
  59&nbsp;     then
 
1194
  60&nbsp;       echo "No files need archiving."
 
1195
  61&nbsp;     fi
 
1196
  62&nbsp;}</PRE
 
1197
></TD
 
1198
></TR
 
1199
></TABLE
 
1200
>
 
1201
      </P
 
1202
><P
 
1203
><A
 
1204
NAME="PTAILGREP"
 
1205
></A
 
1206
></P
 
1207
><P
 
1208
>        A lookalike problem occurs when trying to write the
 
1209
        <TT
 
1210
CLASS="FILENAME"
 
1211
>stdout</TT
 
1212
> of a <B
 
1213
CLASS="COMMAND"
 
1214
>tail -f</B
 
1215
>
 
1216
        piped to <A
 
1217
HREF="textproc.html#GREPREF"
 
1218
>grep</A
 
1219
>.
 
1220
          <TABLE
 
1221
BORDER="0"
 
1222
BGCOLOR="#E0E0E0"
 
1223
WIDTH="90%"
 
1224
><TR
 
1225
><TD
 
1226
><PRE
 
1227
CLASS="PROGRAMLISTING"
 
1228
>   1&nbsp;tail -f /var/log/messages | grep "$ERROR_MSG" &#62;&#62; error.log
 
1229
   2&nbsp;#  The "error.log" file will not have anything written to it.
 
1230
   3&nbsp;#  As Samuli Kaipiainen points out, this results from grep
 
1231
   4&nbsp;#+ buffering its output.
 
1232
   5&nbsp;#  The fix is to add the "--line-buffered" parameter to grep.</PRE
 
1233
></TD
 
1234
></TR
 
1235
></TABLE
 
1236
>
 
1237
      </P
 
1238
></LI
 
1239
><LI
 
1240
><P
 
1241
><A
 
1242
NAME="SUIDSCR"
 
1243
></A
 
1244
></P
 
1245
><P
 
1246
>Using <SPAN
 
1247
CLASS="QUOTE"
 
1248
>"suid"</SPAN
 
1249
> commands within scripts is risky,
 
1250
        as it may compromise system security.
 
1251
          <A
 
1252
NAME="AEN19504"
 
1253
HREF="#FTN.AEN19504"
 
1254
>[1]</A
 
1255
>
 
1256
      </P
 
1257
></LI
 
1258
><LI
 
1259
><P
 
1260
><A
 
1261
NAME="CGIREF"
 
1262
></A
 
1263
></P
 
1264
><P
 
1265
>Using shell scripts for CGI programming may be problematic. Shell
 
1266
        script variables are not <SPAN
 
1267
CLASS="QUOTE"
 
1268
>"typesafe,"</SPAN
 
1269
> and this can cause
 
1270
        undesirable behavior as far as CGI is concerned. Moreover, it is
 
1271
        difficult to <SPAN
 
1272
CLASS="QUOTE"
 
1273
>"cracker-proof"</SPAN
 
1274
> shell scripts.</P
 
1275
></LI
 
1276
><LI
 
1277
><P
 
1278
>Bash does not handle the <A
 
1279
HREF="internal.html#DOUBLESLASHREF"
 
1280
>double slash
 
1281
        (<SPAN
 
1282
CLASS="TOKEN"
 
1283
>//</SPAN
 
1284
>) string</A
 
1285
> correctly.</P
 
1286
></LI
 
1287
><LI
 
1288
><P
 
1289
><A
 
1290
NAME="GNUREF"
 
1291
></A
 
1292
></P
 
1293
><P
 
1294
>Bash scripts written for Linux or BSD systems may need
 
1295
        fixups to run on a commercial UNIX (or Apple OSX) machine. Such
 
1296
        scripts often employ the GNU set of commands and filters,
 
1297
        which have greater functionality than their generic UNIX
 
1298
        counterparts. This is particularly true of such text processing
 
1299
        utilites as <A
 
1300
HREF="textproc.html#TRREF"
 
1301
>tr</A
 
1302
>.</P
 
1303
></LI
 
1304
></UL
 
1305
><TABLE
 
1306
BORDER="0"
 
1307
WIDTH="100%"
 
1308
CELLSPACING="0"
 
1309
CELLPADDING="0"
 
1310
CLASS="EPIGRAPH"
 
1311
><TR
 
1312
><TD
 
1313
WIDTH="45%"
 
1314
>&nbsp;</TD
 
1315
><TD
 
1316
WIDTH="45%"
 
1317
ALIGN="LEFT"
 
1318
VALIGN="TOP"
 
1319
><I
 
1320
><P
 
1321
><I
 
1322
>Danger is near thee --</I
 
1323
></P
 
1324
><P
 
1325
><I
 
1326
>Beware, beware, beware, beware.</I
 
1327
></P
 
1328
><P
 
1329
><I
 
1330
>Many brave hearts are asleep in the deep.</I
 
1331
></P
 
1332
><P
 
1333
><I
 
1334
>So beware --</I
 
1335
></P
 
1336
><P
 
1337
><I
 
1338
>Beware.</I
 
1339
></P
 
1340
><P
 
1341
><I
 
1342
>--A.J. Lamb and H.W. Petrie</I
 
1343
></P
 
1344
></I
 
1345
></TD
 
1346
></TR
 
1347
></TABLE
 
1348
></DIV
 
1349
><H3
 
1350
CLASS="FOOTNOTES"
 
1351
>Notes</H3
 
1352
><TABLE
 
1353
BORDER="0"
 
1354
CLASS="FOOTNOTES"
 
1355
WIDTH="100%"
 
1356
><TR
 
1357
><TD
 
1358
ALIGN="LEFT"
 
1359
VALIGN="TOP"
 
1360
WIDTH="5%"
 
1361
><A
 
1362
NAME="FTN.AEN19504"
 
1363
HREF="gotchas.html#AEN19504"
 
1364
>[1]</A
 
1365
></TD
 
1366
><TD
 
1367
ALIGN="LEFT"
 
1368
VALIGN="TOP"
 
1369
WIDTH="95%"
 
1370
><P
 
1371
>Setting the <A
 
1372
HREF="fto.html#SUIDREF"
 
1373
>suid</A
 
1374
>
 
1375
          permission on the script itself has no effect in Linux
 
1376
          and most other UNIX flavors.</P
 
1377
></TD
 
1378
></TR
 
1379
></TABLE
 
1380
><DIV
 
1381
CLASS="NAVFOOTER"
 
1382
><HR
 
1383
ALIGN="LEFT"
 
1384
WIDTH="100%"><TABLE
 
1385
SUMMARY="Footer navigation table"
 
1386
WIDTH="100%"
 
1387
BORDER="0"
 
1388
CELLPADDING="0"
 
1389
CELLSPACING="0"
 
1390
><TR
 
1391
><TD
 
1392
WIDTH="33%"
 
1393
ALIGN="left"
 
1394
VALIGN="top"
 
1395
><A
 
1396
HREF="options.html"
 
1397
ACCESSKEY="P"
 
1398
>Prev</A
 
1399
></TD
 
1400
><TD
 
1401
WIDTH="34%"
 
1402
ALIGN="center"
 
1403
VALIGN="top"
 
1404
><A
 
1405
HREF="index.html"
 
1406
ACCESSKEY="H"
 
1407
>Home</A
 
1408
></TD
 
1409
><TD
 
1410
WIDTH="33%"
 
1411
ALIGN="right"
 
1412
VALIGN="top"
 
1413
><A
 
1414
HREF="scrstyle.html"
 
1415
ACCESSKEY="N"
 
1416
>Next</A
 
1417
></TD
 
1418
></TR
 
1419
><TR
 
1420
><TD
 
1421
WIDTH="33%"
 
1422
ALIGN="left"
 
1423
VALIGN="top"
 
1424
>Options</TD
 
1425
><TD
 
1426
WIDTH="34%"
 
1427
ALIGN="center"
 
1428
VALIGN="top"
 
1429
><A
 
1430
HREF="part5.html"
 
1431
ACCESSKEY="U"
 
1432
>Up</A
 
1433
></TD
 
1434
><TD
 
1435
WIDTH="33%"
 
1436
ALIGN="right"
 
1437
VALIGN="top"
 
1438
>Scripting With Style</TD
 
1439
></TR
 
1440
></TABLE
 
1441
></DIV
 
1442
></BODY
 
1443
></HTML
 
1444
>
 
 
b'\\ No newline at end of file'