home *** CD-ROM | disk | FTP | other *** search
/ Hackers Toolkit v2.0 / Hackers_Toolkit_v2.0.iso / HTML / archive / Texts / bourne1.txt < prev    next >
Text File  |  1999-11-04  |  73KB  |  1,742 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.                    UNIX Bourne Shell Programming
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.                     Developed by:
  43.  
  44.                          User Liaison Section, D-7131
  45.                          Denver Office
  46.    
  47.                     [Name and number removed at author's
  48.                      request]
  49.  
  50.                     Revision Date:  February 7, 1991
  51.  
  52.  
  53. I.  INTRODUCTION..............................................  v
  54.      A.  Audience.............................................  v
  55.      B.  Course Objectives....................................  v
  56.      C.  Course Handout Conventions........................... vi
  57.  
  58. 1.  BOURNESHELL OVERVIEW......................................  1
  59.      1.1  What is the BourneShell?............................  2
  60.      1.2  Making a Bourne Shell Script Executable.............  3
  61.      1.3  Tracing Mechanisms..................................  6
  62.      Workshop 1...............................................  9
  63.  
  64. 2.  USER, SHELL, AND READ-ONLY SHELL VARIABLES................ 11
  65.      2.1  User Variables...................................... 11
  66.      2.2  Shell Variables..................................... 14
  67.           2.2.1  HOME......................................... 14
  68.           2.2.2  IFS.......................................... 15
  69.           2.2.3  MAIL......................................... 15
  70.           2.2.4  MAILPATH..................................... 15
  71.           2.2.5  MAILCHECK.................................... 16
  72.           2.2.6  PATH......................................... 16
  73.           2.2.7  PS1.......................................... 17
  74.           2.2.8  PS2.......................................... 17
  75.      2.3  Read-Only User Variables............................ 18
  76.      2.4  Read-Only Shell Variables........................... 19
  77.           2.4.1  Name of the Calling Program.................. 19
  78.           2.4.2  Arguments.................................... 19
  79.           2.4.3  Shift........................................ 21
  80.           2.4.4  Set.......................................... 22
  81.           2.4.5  expr......................................... 23
  82.      Workshop 2............................................... 27
  83.  
  84. 3.  POSITIONAL PARAMETERS..................................... 33
  85.      3.1  Reading Input Into a Shell Variable................. 34
  86.      3.2  Command Substitution................................ 36
  87.      3.3  Comments in BourneShell Scripts..................... 38
  88.      3.4  BourneShell Environment - Exporting Variables....... 39
  89.      Workshop 3............................................... 41
  90.  
  91. 4.  CONTROL CONSTRUCTS:....................................... 45
  92.      4.1  Types of Tests Used with Control Constructs:........ 46
  93.      4.2  Test on Numeric Values.............................. 47
  94.      4.3  Test on Character Strings........................... 47
  95.      4.4  Test on File Types.................................. 49
  96.      4.5  if then............................................. 50
  97.      4.6  if then else........................................ 52
  98.      4.7  if then elif........................................ 54
  99.      4.8  for................................................. 55
  100.      4.9  while............................................... 57
  101.      4.10  until.............................................. 58
  102.      4.11  case............................................... 60
  103.      Workshop 4............................................... 63
  104.  
  105. 5. COMPILING PROGRAMS IN UNIX................................. 67
  106.      5.1  "C": Sample Program with a Main and Two Functions
  107.                in One        ................................. 67
  108.      5.2  "C": Compiling a Program............................ 69
  109.      5.3  "C": Renaming the Executable Module................. 71
  110.      5.4  "C": Giving a Name to the Output File............... 72
  111.      5.5  "C": Producing an Assembly Listing.................. 73
  112.      5.6  "C": Main and Two Functions in Three Separate Source
  113.                Files.......................................... 74
  114.      5.7  "C": Compiling but Not Producing an Executable    
  115.            Module............................................. 75
  116.      5.8  FORTRAN: Sample Program a Main and Two Subroutine... 76
  117.      5.9  FORTRAN: Compiling a Program........................ 77
  118.      5.10  FORTRAN: Renaming the Executable Module............ 79
  119.      5.11  FORTRAN: Giving a Name to the Output File.......... 80
  120.      5.12  FORTRAN: Producing an Assembly Listing............. 81
  121.      5.13  FORTRAN: Main and Two Subroutines in Three Separate
  122.                     Source Files.............................. 82
  123.      5.14  FORTRAN: Compiling But Not Producing an Executable
  124.                     Module.................................... 83
  125.      5.15  FORTRAN: Compiling Object Files to Produce an    
  126.                 Executable Module............................. 84
  127.      5.16  COBOL: Sample Program with a Main and Two        
  128.                   Subroutines................................. 85
  129.      5.17  COBOL: Compiling a Program......................... 86
  130.      5.18  COBOL: Running a Program........................... 87
  131.      Workshop 5............................................... 89
  132.  
  133. 6.  UNIX TOOLS................................................ 95
  134.      6.1  Processes........................................... 95
  135.      6.2  Executing a Command................................. 95
  136.      6.3  Process Identification.............................. 95
  137.      6.4  grep: A Pattern Matching Filter..................... 98
  138.           6.4.1  More on Regular Expressions.................. 99
  139.           6.4.2  Closure......................................103
  140.           6.4.3  Some Nice grep Options ......................104
  141.           6.4.4  Summary of Regular Expression Characters.....105
  142.      6.5  sed: Edit a File to Standard Output.................106
  143.      6.6  awk: A Pattern Matching Programming Language........110
  144.      6.7  sort: Sort a File...................................114
  145.      6.8  What Other Useful UNIX Tools are Available..........117
  146.      6.9  Archiver and Library Maintainer.....................118
  147.           6.9.1  ar: Creating an Archive File with Object   
  148.                   Modules.....................................119
  149.           6.9.2  ar: Verifying the Contents of the Archive  
  150.                    File.......................................119
  151.           6.9.3  ar: Removing Duplicate Object Files..........120
  152.           6.9.4  ar: Compiling Main and Archive Files.........120
  153.      Workshop 6...............................................121
  154.  
  155.  
  156. 7.  VAX DCL TO UNIX SHELL SCRIPT CONVERSION...................125
  157.      7.1  Processes...........................................127
  158.      7.2  Pipes...............................................128
  159.      7.3  Input, Output, and Error Redirection................129
  160.      7.4  Command Structure and File Naming Conventions.......131
  161.      7.5  File Management Commands............................133
  162.      7.6  Metacharacters......................................135
  163.      7.7  Wildcards: Are They Really Wild?....................136
  164.      7.8  Summary.............................................137
  165.      Workshop 7...............................................139
  166.  
  167. 8.  ADVANCED FEATURES OF FTP..................................143
  168.      8.1  Initializing FTP on UMAX............................144
  169.      8.2  Multiple File Transfers.............................145
  170.      8.3  Auto Login Feature..................................146
  171.      8.4  Macros..............................................148
  172.      8.5  Filename Translation................................149
  173.      8.6  Aborting Transfers..................................150
  174.      8.7  More Remote Computer Commands.......................151
  175.      Workshop 8...............................................153
  176.  
  177. 9.  OPTIONAL CHAPTER - KORNSHELL PROGRAMMING..................155
  178.      9.1  KornShell Variables.................................155
  179.      9.2  User Defined Variables..............................157
  180.      9.3  Values of Variables Between Child and Parent
  181.           Processes...........................................158
  182.      9.4  ksh: Aliases........................................159
  183.      9.5  ksh: Command Line Editing...........................161
  184.      9.6  ksh: Interactive Command Line Editing...............162
  185.      9.7  ksh: Functions......................................164
  186.      9.8  ksh: The Select Construct...........................166
  187.      9.9  ksh: Tracing and Conditional Execution..............168
  188.      Workshop 9...............................................169
  189.  
  190. APPENDIX A - sh...............................................173
  191.  
  192. APPENDIX B - test.............................................189
  193.  
  194. APPENDIX C - expr.............................................193
  195.  
  196. APPENDIX D - ftp..............................................195
  197.  
  198. APPENDIX E - cc...............................................209
  199.  
  200. APPENDIX F - f77..............................................219
  201.  
  202. APPENDIX G - lint.............................................231
  203.  
  204. APPENDIX H - cb...............................................235
  205.  
  206. APPENDIX I - ar...............................................237
  207.  
  208. APPENDIX J - time.............................................243
  209.  
  210. APPENDIX K - ksh..............................................245
  211.  
  212. INDEX.........................................................279
  213.  
  214. I.  INTRODUCTION
  215.  
  216.  
  217. A.  Audience
  218.  
  219.  
  220. This course is for individuals who have completed "UNIX for
  221. Beginning Users" (or equivalent experience) and want to write UNIX
  222. BourneShell script files.  A script file contains a sequence of
  223. UNIX commands which can be executed by entering one command.  It
  224. is assumed that the student already has a good understanding of the
  225. UNIX operating system, be able to use a UNIX editor, and be
  226. familiar with a computer terminal or typewriter keyboard.
  227.  
  228.  
  229.  
  230. B.  Course Objectives
  231.  
  232.  
  233. Upon successful completion of this course the student will be able
  234. to:
  235.  
  236.      1.   Write moderately complex BourneShell scripts.
  237.  
  238.      2.   Make a BourneShell script executable.
  239.  
  240.      3.   Demonstrate how to use the following BourneShell
  241.           commands: shift, exit, expr, test, if then, if then else,
  242.           if then elif, for, while, until, and case.
  243.  
  244.      4.   Use the following BourneShell constructs: tracing
  245.           mechanisms (for debugging), user variables, BourneShell
  246.           variables, read-only variables, positional parameters,
  247.           reading input to a BourneShell script, command
  248.           substitution, comments, and exporting variables.  In
  249.           addition, test on numeric values, test on file type, and
  250.           test on character strings are covered.
  251.  
  252.      6.   Create a ".profile" script to customize the user
  253.           environment.
  254.  
  255.      7.   Use advanced features of File Transfer Protocol (FTP)
  256.  
  257.      8.   Compile source code into object and executable modules.
  258.  
  259.      9.   Optional: KornShell programming.  This is of primary
  260.           interest to programmers.
  261.  
  262.      10.  Convert VMS DCL command files to UNIX Shell.
  263. C.  Course Handout Conventions
  264.  
  265.  
  266. There are several conventions used in this handout for consistency
  267. and easier interpretation:
  268.  
  269.  
  270.      1.   Samples of actual terminal sessions are single-lined
  271.           boxed.
  272.  
  273.  
  274.      2.   User entries are shown in bold print and are underlined.
  275.  
  276.           exit
  277.  
  278.  
  279.      3.   All keyboard functions in the text will be bold.  
  280.  
  281.           (Ret)               Backspace
  282.           Tab                 Ctrl-F6
  283.           Print (Shift-F7)    Go to DOS (1)
  284.  
  285.           NOTE:     (Ret) indicates the Return or Enter key located
  286.                     above the right Shift key.
  287.  
  288.  
  289.      4.   Examples of user entries not showing the computer's
  290.           response are in dotted-lined boxes.                   
  291.            
  292.  
  293.  
  294.      5.   Command formats are double-lined boxed.
  295.  
  296.  
  297.  
  298.      6.   Three dots either in vertical or horizontal alignment
  299.           mean continuation or that data is missing from diagram.
  300.  
  301.                                                                  
  302. ┌───────────────────────────────────────────────────────────────┐
  303. │                                                               │
  304. │        Multimax, Nanobus, and UMAX are trademarks of          │
  305. │        Encore Computer Corporation.                           │
  306. │                                                               │
  307. │                                                               │
  308. │        Annex is a trademark of XYLOGICS, Inc.                 │
  309. │                                                               │
  310. │                                                               │
  311. │        UNIX and Teletype are registered trademarks of         │
  312. │        AT&T Bell Laboratories                                 │
  313. │                                                               │
  314. │                                                               │
  315. │        Ethernet is a trademark of Xerox Corporation           │
  316. │                                                               │
  317. └───────────────────────────────────────────────────────────────┘
  318.                                NOTES
  319. ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  320. 1.  BOURNESHELL OVERVIEW
  321.  
  322.  
  323. The BourneShell is both a command-line interpreter and a high-
  324. level programming language.  When it is acting as a command-line
  325. interpreter, it processes commands as you enter them at the command
  326. prompt.  When you use it as a programming language, it processes
  327. commands that are stored in files known as BourneShell scripts. 
  328. This course will show you how to create and execute BourneShell
  329. scripts.  We will explore BourneShell programming including such
  330. features as variables, control structures, processes, and
  331. executable files.
  332.  
  333.  
  334. The BourneShell is one of three shells available on most UNIX
  335. systems.  Bourne is the accepted standard for System V UNIX.  The
  336. other shells are being used more and more.  The other shells are
  337. the CShell and the KornShell.  The CShell is BSD (Berkeley Software
  338. Distribution) UNIX. BSD was developed at the University of
  339. California at Berkeley, California. Most of the features found in
  340. the BourneShell are also found in the other shells; there are
  341. differences, however.  The CShell and KornShell are not standard
  342. on UNIX System V but are generally available.
  343.  
  344.  
  345. BourneShell scripts allow you to group command lines together and
  346. execute them by entering a single command at the command line. This
  347. allows complex functions to be completed by any user, and
  348. repetitive functions can be completed easily.  Input and output
  349. can also be redirected from a BourneShell script.
  350. 1.1  What is the BourneShell?
  351.  
  352. BourneShell is a high level programming language and a command line
  353. interpreter. 
  354.  
  355. The command to invoke the BourneShell is:
  356.  
  357. ╔═══════════════════════════════════════════════════════════════╗
  358. ║  Command Format:  sh [-acefhiknrstuvx] [args]                 ║
  359. ║                                                               ║
  360. ║  (See Appendix A for a complete list of options etc)          ║
  361. ╚═══════════════════════════════════════════════════════════════╝
  362.  
  363. A Shell script is an executable plain file that contains UNIX and
  364. shell commands. To execute the shell script type the name of the
  365. script at the prompt. A simple shell script called shell_ex is
  366. shown in the following example. The output from the execution of
  367. the shell is also shown.
  368.  
  369. Sample Session:
  370.  
  371. ┌───────────────────────────────────────────────────────────────┐
  372. │ $cat shell_ex                                                 │
  373. │ echo "This is a very simple shell procedure "                 │
  374. │ echo "created with the basic echo command "                   │
  375. │ echo "and three other very basic commands "                   │
  376. │ echo                                                          │
  377. │ ps                                                            │
  378. │ echo                                                          │ 
  379. │ who                                                           │
  380. │ echo                                                          │
  381. │ ls                                                            │
  382. │ $sh shell_ex                                                  │
  383. │ This is a very simple shell procedure                         │
  384. │ created with the very basic echo command                      │
  385. │ and three other very basic commands                           │
  386. │                                                               │
  387. │ PID    TTY     TIME    COMMAND                                │
  388. │ 10443 rt02120  0:01    sh                                     │
  389. │ 10427 rt02120  0:04    ksh                                    │
  390. │                                                               │
  391. │ sgavlick  rt021e0   Sep 7   13:26                             │
  392. │ teacher   rt021b0   Sep 7   14:39                             │
  393. │                                                               │
  394. │ memo                                                          │
  395. │ class_notes                                                   │
  396. │ $                                                             │
  397. └───────────────────────────────────────────────────────────────┘
  398. 1.2  Making a Bourne Shell Script Executable
  399.  
  400. A BourneShell script is an ordinary file that contains commands
  401. which can be executed in sequence by entering one command at the
  402. BourneShell prompt.  In order for a script to be executed, it must
  403. first be executable.  This is done with the chmod command.
  404.  
  405. Sample Session:
  406.  
  407. ┌───────────────────────────────────────────────────────────────┐
  408. │ $cat shell_ex                                                 │
  409. │ echo "This is a very simple shell procedure "                 │
  410. │ echo "created with the basic echo command "                   │
  411. │ echo "and three other very basic commands "                   │
  412. │ echo                                                          │
  413. │ ps                                                            │
  414. │ echo                                                          │
  415. │ who                                                           │
  416. │ echo                                                          │
  417. │ ls                                                            │
  418. │ $                                                             │
  419. └───────────────────────────────────────────────────────────────┘
  420.  
  421. If the ls -l shell_ex command were entered, we would see the
  422. protections assigned to this file.
  423.  
  424. Sample Session:
  425.  
  426. ┌───────────────────────────────────────────────────────────────┐
  427. │ $ls -l shell_ex                                               │
  428. │ -rw-r--r-- 1 teacher class  66 Sep 7 10:24 shell_ex           │
  429. │ $                                                             │
  430. └───────────────────────────────────────────────────────────────┘
  431.  
  432. The character in column one is the type of file. 
  433.  
  434.       -  =  ordinary (plain) disk file
  435.  
  436.       d  =  directory
  437.  
  438.       b  =  block special file
  439.  
  440.       c  =  character special file
  441.  
  442.       p  =  fifo file ("named pipe") special file
  443.  
  444.       l  =  symbolic link
  445.  
  446.           
  447.  
  448.  
  449.  
  450. Notice that the script file in the previous sample session has the
  451. following file protections:
  452.  
  453.      User   - Read and Write
  454.      Group  - Read
  455.      Other  - Read
  456.  
  457. No execute permissions have been granted for user, group, or other. 
  458. If we try to execute this script by typing its name, the following
  459. would result.
  460.  
  461. Sample Session:
  462.  
  463. ┌───────────────────────────────────────────────────────────────┐
  464. │ $shell_ex                                                     │
  465. │ shell_ex: execute permission denied                           │
  466. │ $                                                             │
  467. └───────────────────────────────────────────────────────────────┘
  468.  
  469. This error message would indicate that execute permission was
  470. denied.  The BourneShell script could not be executed.  To change
  471. the permissions for the BourneShell script, use the chmod command.
  472.  
  473. Sample Session:
  474.  
  475. ┌───────────────────────────────────────────────────────────────┐
  476. │ $chmod 755 shell_ex                                           │
  477. │ $ls -l shell_ex                                               │
  478. │ -rwxr-xr-x 1 teacher class  66 Sep 7  10:26 shell_ex          │
  479. │ $                                                             │
  480. └───────────────────────────────────────────────────────────────┘
  481.  
  482.  
  483. Now that the permissions have been changed to allow user, group,
  484. and others to execute the file, it will execute properly.
  485. Sample Session:
  486.  
  487. ┌───────────────────────────────────────────────────────────────┐
  488. │ $shell_ex                                                     │
  489. │ This is a very simple shell procedure                         │
  490. │ created with the basic echo command                           │
  491. │ and three other very basic commands                           │
  492. │                                                               │
  493. │ PID    TTY     TIME    COMMAND                                │
  494. │ 10443 rt02120  0:01    sh                                     │
  495. │ 10427 rt02120  0:04    ksh                                    │
  496. │                                                               │
  497. │ sgavlick  rt021e0   Sep 7   13:26                             │
  498. . teacher   rt021b0   Sep 7   14:39                             .
  499. .                                                               .
  500. .                                                               .
  501.  
  502.  
  503. The protections will work as you expect.  Execute permission for
  504. the user will allow you (the owner) to run the BourneShell script.
  505. Group permissions allow anyone in your group to execute the script,
  506. and other permission allows anyone on the system to execute the
  507. script.
  508. 1.3  Tracing Mechanisms
  509.  
  510. It is possible to have a trace made of the BourneShell script as
  511. it executes. This is invaluable for debugging purposes. All that
  512. is required is to give an option to the BourneShell.   This is done
  513. by including an option on the call to "sh". The command to do this
  514. is:
  515.  
  516. ╔═══════════════════════════════════════════════════════════════╗
  517. ║     Command Format: sh [-acefhiknrstuvx] [args]               ║
  518. ║                                                               ║
  519. ║     See Appendix A for a complete list of options etc         ║
  520. ║                                                               ║
  521. ╚═══════════════════════════════════════════════════════════════╝
  522.  
  523. The option to turn on tracing is -x. For an example, let's trace
  524. the execution of the simple script shell_ex.
  525.  
  526. Sample session:
  527.  
  528. ┌───────────────────────────────────────────────────────────────┐
  529. │     $cat shell_ex                                             │
  530. │     echo "This is a very simple shell procedure "             │
  531. │     echo "created with the basic echo command "               │
  532. │     echo "and three other very basic commands "               │
  533. │     echo                                                      │
  534. │     ps                                                        │
  535. │     echo                                                      │
  536. │     who                                                       │
  537. │     echo                                                      │
  538. │     ls                                                        │
  539. │     $                                                         │
  540. └───────────────────────────────────────────────────────────────┘
  541.  
  542. Execute the BourneShell script using the -x option on the call to
  543. the shell. The following sample session shows how to do this and
  544. it shows the results of the trace.
  545. Sample session:
  546.  
  547. ┌───────────────────────────────────────────────────────────────┐
  548. │     $sh -x shell_ex                                           │
  549. │     + echo This is a very simple shell procedure              │
  550. │     This is a very simple shell procedure                     │
  551. │     + echo created with the basic echo command                │
  552. │     created with the basic echo command                       │
  553. │     + echo and three other very basic commands                │
  554. │     and three other very basic commands                       │
  555. │     + echo                                                    │
  556. │                                                               │
  557. │     + ps                                                      │
  558. │     PID    TTY      TIME       COMMAND                        │
  559. │     10443 rt01120   0:01       sh                             │
  560. │     10427 rt02120   0:04       ksh                            │
  561. │     + echo                                                    │
  562. │                                                               │
  563. │     + who                                                     │
  564. │     sgavlick  rt021e0   Sep 7  13:26                          │
  565. │     teacher   rt02120   Sep 7  14:39                          │
  566. │     + echo                                                    │
  567. │                                                               │
  568. │     + ls                                                      │
  569. │     memo                                                      │
  570. │     class_notes                                               │
  571. │     $                                                         │
  572. └───────────────────────────────────────────────────────────────┘
  573.  
  574. The commands as read from the BourneShell script are indicated by
  575. the plus sign (+). The next line or lines are the results of the
  576. execution of the command. Using this tracing option allows you to
  577. se the execution of each command in the script and see the results
  578. of that execution.
  579.                                NOTES
  580. ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  581. Workshop 1
  582.  
  583. This workshop will reinforce your understanding of the ideas
  584. presented in Chapter 1. Each student is to complete the entire
  585. workshop.
  586.  
  587. DESK EXERCISES 
  588.  
  589.  
  590.      1.   The BourneShell can act as a command line
  591.  
  592.                                                    
  593.  
  594.           or a high level                          .  
  595.  
  596.  
  597.  
  598.  
  599.      2.   The BourneShell is one of three shells generally
  600.           available. What are the other two?
  601.  
  602.  
  603.  
  604.  
  605.      3.   One advantage of using a shell script is
  606.  
  607.                                                   .
  608.  
  609.  
  610.  
  611.      4.   The command to call the BourneShell is:
  612.  
  613.           a.   bourne
  614.           b.   ksh
  615.           c.    b
  616.           d.   sh
  617.  
  618.  
  619.  
  620.  
  621.      5.   Why would you use tracing?
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628.      6.   What UNIX command do you enter to make a BourneShell
  629.           script executable? 
  630.  
  631.  
  632.      That's all
  633.                                NOTES
  634. ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  635. 2.  USER, SHELL, AND READ-ONLY SHELL VARIABLES
  636.  
  637.  
  638. The BourneShell has no true numeric variables.  It uses string
  639. variables to represent numbers, as well as text.  String variables
  640. are able to take on the value of a string of characters.  There are
  641. three types of variables in the BourneShell.  They are user
  642. variables, BourneShell variables, and Read-only BourneShell
  643. variables.
  644.  
  645. You can declare, initialize, read, and modify user variables from
  646. a BourneShell script or from the command line.  The BourneShell
  647. itself declares and initializes shell variables, but you can read
  648. and modify them.  The BourneShell also initializes the read-only
  649. shell variables, and you can read but not modify them.
  650.  
  651.  
  652.  
  653. 2.1  User Variables
  654.  
  655.  
  656. It is legal to assign any sequence of non-blank characters as the
  657. name of a variable.  The sample session below creates a variable
  658. called person and initializes it with the string Richard.
  659.  
  660. It is important to note that you must NOT precede or follow the
  661. equal sign with a space or TAB character.
  662.  
  663. Sample Session:
  664.                         
  665. ┌───────────────────────────────────────────────────────────────┐
  666. │  $person=Richard                                              │
  667. └───────────────────────────────────────────────────────────────┘
  668.                                                                  
  669.  
  670. This sample session indicates that person does not represent the 
  671. string Richard.  The string person is echoed as person.  The
  672. BourneShell will only do the substitution of the value of the
  673. variable when the name of the variable is preceded with a dollar
  674. sign ($).  
  675.  
  676. Sample Sesssion:
  677.                 
  678. ┌───────────────────────────────────────────────────────────────┐
  679. │  $echo person                                                 │
  680. │  person                                                       │
  681. │  $echo $person                                                │
  682. │  Richard                                                      │
  683. │  $                                                            │
  684. └───────────────────────────────────────────────────────────────┘
  685. If you want to have imbedded spaces in a variable, it is necessary
  686. to quote the string.
  687.  
  688. Sample Session:
  689.  
  690. ┌───────────────────────────────────────────────────────────────┐
  691. │  $person='Richard and Kathleen'                               │
  692. │  $echo $person                                                │
  693. │  Richard and Kathleen                                         │
  694. │  $                                                            │
  695. └───────────────────────────────────────────────────────────────┘
  696.  
  697. The echo utility copies its arguments to the standard output.  The
  698. command echo $person displays the value of the variable person. 
  699. It will not display $person because the BourneShell doesn't pass
  700. $person as an argument.  The leading dollar sign ($) causes the
  701. BourneShell to substitute the value of the variable and then passes
  702. that value to the utility.  The echo utility then displays the
  703. value of the variable, not its name, never knowing that you called
  704. it with a variable.  The BourneShell passed the same command line
  705. as if you had typed in echo Richard and Kathleen.  The BourneShell
  706. can be prevented from doing this substitution by entering one of
  707. the following:
  708.  
  709. Sample Sessions:
  710.  
  711. ┌───────────────────────────────────────────────────────────────┐
  712. │  $echo $person                                                │
  713. │  Richard and Kathleen                                         │
  714. │  $                                                            │
  715. └───────────────────────────────────────────────────────────────┘
  716.                                                                  
  717. In this session the contents of the variable person are displayed.
  718. The BourneShell made the substitution because the variable name
  719. person is preceded by a dollar sign ($).
  720.  
  721. ┌───────────────────────────────────────────────────────────────┐
  722. │  $echo \$person                                               │
  723. │  $person                                                      │
  724. │  $                                                            │
  725. └───────────────────────────────────────────────────────────────┘
  726.  
  727. In the above example the variable person is preceded by a dollar
  728. sign ($) but the dollar sign has a backslash (\) ahead of it. The
  729. backslash has the effect of cancelling the special meaning of the
  730. character following the backslash. In this case, the special
  731. meaning of the dollar sign is ignored and the substitution is not
  732. done.
  733.  
  734.  
  735.  
  736.  
  737. ┌───────────────────────────────────────────────────────────────┐
  738. │  $echo '$person'                                              │
  739. │  $person                                                      │
  740. │  $                                                            │
  741. └───────────────────────────────────────────────────────────────┘
  742.  
  743.  
  744. The single quote marks (') causes the characters between the marks
  745. to be taken as literal. The shell makes no attempt to interpret the
  746. meanings of these characters. The shell passes these characters on
  747. with no substitution. 
  748.  
  749. ┌───────────────────────────────────────────────────────────────┐
  750. │  $echo "$person"                                              │
  751. │  Richard and Kathleen                                         │
  752. │  $                                                            │
  753. └───────────────────────────────────────────────────────────────┘
  754.  
  755. The double quote marks do not prevent the shell from making
  756. substitution; and the value of the variable will be displayed by
  757. the utility.
  758. 2.2  Shell Variables
  759.  
  760.  
  761. The BourneShell declares and initializes variables that determine
  762. such things as your home directory, what directories the shell will
  763. look in when you give commands, how often to look for mail, your
  764. prompt, and many other things.  We will look at several of these
  765. BourneShell variables and their functions.  You can assign new
  766. values to these variables from the command line or from the
  767. execution of the .profile file in your home directory.
  768.  
  769. 2.2.1  HOME
  770.  
  771. The first BourneShell variable that we will look at is the HOME
  772. variable.  By default, the home directory is the current working
  773. directory after you login.  The system administrator determines
  774. your home directory when you establish an account and places that
  775. information in the /etc/passwd file.  When you login, the
  776. BourneShell gets that pathname and assigns it to the HOME variable.
  777.  
  778. When you enter a cd command with no argument, the utility takes
  779. the name of the directory from the HOME variable and makes it the
  780. current working directory.  If you change the HOME variable to
  781. another directory pathname, the utility will make the new directory
  782. the current working directory.
  783.  
  784. Sample Session:
  785.  
  786. ┌───────────────────────────────────────────────────────────────┐
  787. │ $echo $HOME                                                   │
  788. │ /user0/rharding                                               │
  789. │ $cd                                                           │
  790. │ $pwd                                                          │
  791. │ /user0/rharding                                               │
  792. │ $HOME=/user0/rharding/eng                                     │
  793. │ $cd                                                           │
  794. │ $pwd                                                          │
  795. │ /user0/rharding/eng                                           │
  796. │ $                                                             │
  797. └───────────────────────────────────────────────────────────────┘
  798.  
  799. This example shows how the value of the HOME variable affects the
  800. cd utility.  The cd command will use the value of the HOME variable
  801. as the pathname for the current working directory.
  802. 2.2.2  IFS
  803.  
  804. This is the internal-field separator BourneShell variable.  You
  805. can always use a space or tab to separate characters on the command
  806. line.  When you assign the IFS variable to another character, you
  807. can also use this character as the field separator.
  808.  
  809. Example:
  810. .................................................................
  811. . $num_args a:b:c:d                                             .
  812. .................................................................
  813.  
  814. This example shows only one argument, namely a:b:c:d.
  815. .................................................................
  816. .  $IFS=:                                                       .
  817. .  $num_args a:b:c:d                                            .
  818. .................................................................
  819.  
  820. This example now shows four different arguments; each being
  821. separated by the new IFS, (:).
  822.  
  823. 2.2.3  MAIL
  824.  
  825. The MAIL variable contains the name of the file that the mail (and
  826. mailx) utilities use to store your mail.  Usually, the absolute
  827. pathname of this file is /usr/mail/name, where name is your login
  828. name.
  829.  
  830. Example:
  831. .................................................................
  832. . $MAIL=/usr/mail/rharding                                      .
  833. .................................................................
  834.  
  835. 2.2.4  MAILPATH
  836.  
  837. This variable contains a list of filenames separated by colons. If
  838. set, the BourneShell will inform you when any of these files are
  839. modified (i.e. when new mail arrives).  Normally, this variable is
  840. not set.
  841. 2.2.5  MAILCHECK
  842.  
  843. This variable specifies how often, in seconds, the BourneShell will
  844. check for new mail.  The default is 600 seconds.  If set to 0, it
  845. will check for new mail each time before it gives you a prompt.
  846.  
  847. 2.2.6  PATH
  848.  
  849. This BourneShell variable will describe the directories that will
  850. be searched looking for the program that you want to execute.  The
  851. BourneShell looks in several directories for a file that has the
  852. same name as the command that you entered.  The PATH variable
  853. controls this search path. Normally, the first directory searched
  854. is the current working directory.  If the program is not found,
  855. the search continues in the /bin and then the /usr/bin directory. 
  856. Generally, these directories contain executable programs.  If the
  857. program is not found in one of these directories, the BourneShell
  858. reports that the program can't be found (or executed).
  859.  
  860. The PATH variable lists the pathnames in the order in which the
  861. search will proceed.  The pathnames are separated by a colon (:).
  862. If nothing (null string) precedes the colon, that indicates to
  863. start the search at the current working directory.
  864.  
  865. Example:
  866. .................................................................
  867. . $PATH=:/user0/rharding/bin:/bin:/usr/bin                      .
  868. . $                                                             .
  869. .................................................................
  870.  
  871. This PATH variable indicates to start the search for the program
  872. at the current working directory, then look in the directory
  873. /user0/rharding/bin, then /bin, and finally /usr/bin.
  874.  
  875. If each user has a unique path specified, each user can execute a
  876. different program by giving the same command.  The search for the
  877. program stops when it is satisfied; thus, you can use the same name
  878. for your own programs as the standard UNIX utilities.  To do this,
  879. simply put your program in one of the first directories that the
  880. BourneShell searches.
  881. 2.2.7  PS1
  882.  
  883. This is the BourneShell prompt which lets you know that the shell
  884. is waiting for you to give it a command.  The default BourneShell
  885. prompt is a dollar sign ($).  The shell stores the prompt as a
  886. string variable in PS1.  When you change the value of this
  887. variable, the appearance of the prompt will change.  When you are
  888. working on several different machines, it might be useful to have
  889. the prompt be the name of the machine you are working on.
  890.  
  891. Sample Session:
  892.  
  893. ┌───────────────────────────────────────────────────────────────┐
  894. │ $pwd                                                          │
  895. │ /user0/rharding                                               │
  896. │ $PS1='domax0: '                                               │
  897. │ domax0:                                                       │
  898. └───────────────────────────────────────────────────────────────┘
  899.  
  900. Notice that prompt is now domax0:
  901.  
  902. 2.2.8  PS2
  903.  
  904. This variable is called the secondary prompt.  If the command is
  905. not completed on one line and must be continued on the next line,
  906. the prompt for that continued line is PS2.  The default is >. This
  907. prompt indicates that the BourneShell is expecting you to finish
  908. the previous command line.
  909.  
  910. Sample Session:
  911.  
  912. ┌───────────────────────────────────────────────────────────────┐
  913. │ $echo 'demonstration of prompt string                         │
  914. │ >2'                                                           │
  915. │ demonstration of prompt string                                │
  916. │ 2                                                             │
  917. │ $PS2='Continue? '                                             │
  918. │ $echo 'demonstration of                                       │
  919. │ Continue? prompt string 2'                                    │
  920. │ demonstration of                                              │
  921. │ prompt string 2                                               │
  922. │ $                                                             │
  923. └───────────────────────────────────────────────────────────────┘
  924.  
  925. Notice how the secondary prompt was changed to "Continue? ".
  926. 2.3  Read-Only User Variables
  927.  
  928. The contents of the user variables and the shell variables can be
  929. modified by the user.  It is possible to assign a new value to
  930. them.  The new value can be assigned from the dollar ($) prompt or
  931. from inside a BourneShell script.  Read-only variables are
  932. different.  The value of read-only variables can not be changed.
  933.  
  934. The variable must be initialized to some value; and then, by
  935. entering the following command, it can be made read only.
  936.  
  937.  
  938. ╔═══════════════════════════════════════════════════════════════╗
  939. ║  Command format:    readonly variable_name                    ║
  940. ║                                                               ║
  941. ║  variable_name = name of the variable to be made read only    ║
  942. ╚═══════════════════════════════════════════════════════════════╝
  943.  
  944. Sample Session:
  945.  
  946. ┌───────────────────────────────────────────────────────────────┐
  947. │ $person=Kathleen                                              │
  948. │ $readonly person                                              │
  949. │ $echo $person                                                 │
  950. │ Kathleen                                                      │
  951. │ $person=Richard                                               │
  952. │ person: is read only                                          │
  953. │ $                                                             │
  954. └───────────────────────────────────────────────────────────────┘
  955.  
  956. The readonly command given without any arguments will display a
  957. list of all the read-only variables.
  958.  
  959. Sample Session:
  960.  
  961. ┌───────────────────────────────────────────────────────────────┐
  962. │ $person=Kathleen                                              │
  963. │ $readonly person                                              │
  964. │ $example=Richard                                              │
  965. │ $readonly example                                             │
  966. │ $readonly                                                     │
  967. │ readonly person                                               │
  968. │ readonly example                                              │
  969. │ $                                                             │
  970. └───────────────────────────────────────────────────────────────┘
  971. 2.4  Read-Only Shell Variables
  972.  
  973. The read-only shell variables are similar to the read-only user
  974. variables; except the value of these variables is assigned by the
  975. shell, and the user CANNOT modify them.
  976.  
  977.  
  978. 2.4.1  Name of the Calling Program
  979.  
  980. The shell will store the name of the command you used to call a
  981. program in the variable named $0.
  982.  
  983. It has the number zero because it appears before the first argument
  984. on the command line.
  985.  
  986. Sample Session:
  987.  
  988. ┌───────────────────────────────────────────────────────────────┐
  989. │ $cat name_ex                                                  │
  990. │ echo 'The name of the command used'                           │
  991. │ echo 'to execute this script was' $0                          │
  992. │ $name_ex                                                      │
  993. │ The name of the command used                                  │
  994. │ to execute this script was name_ex                            │
  995. │ $                                                             │
  996. └───────────────────────────────────────────────────────────────┘
  997.  
  998. 2.4.2  Arguments
  999.  
  1000. The BourneShell will store the first nine command line arguments
  1001. in the variables named $1, $2, ..., $9.  These variables appear in
  1002. this section because you cannot change them using the equal sign. 
  1003. It is possible to modify them using the set command.
  1004.  
  1005. Sample Session:
  1006.  
  1007. ┌───────────────────────────────────────────────────────────────┐
  1008. │ $cat arg_ex                                                   │
  1009. │ echo 'The first five command line'                            │
  1010. │ echo 'arguments are' $1 $2 $3 $4 $5                           │
  1011. │ $arg_ex Richard Kathleen Douglas                              │
  1012. │ The first five command line                                   │
  1013. │ arguments are Richard Kathleen Douglas                        │
  1014. │ $                                                             │
  1015. └───────────────────────────────────────────────────────────────┘
  1016.  
  1017. The script arg_ex will display the first five command-line
  1018. arguments.  The variables representing $4 and $5 have a null value.
  1019.  
  1020. The BourneShell variable $* represents all of the command-line
  1021. arguments as shown in the following example.
  1022.  
  1023. Sample Session:
  1024.  
  1025. ┌───────────────────────────────────────────────────────────────┐
  1026. │ $cat display_all                                              │
  1027. │ echo $*                                                       │
  1028. │ $display_all Richard Kathleen Douglas                         │
  1029. │ Richard Kathleen Douglas                                      │
  1030. │ $                                                             │
  1031. └───────────────────────────────────────────────────────────────┘
  1032.  
  1033. The BourneShell variable $# contains the number of arguments on
  1034. the command line.  This is a string variable that represents a
  1035. decimal number.  You can use the expr utility to perform
  1036. calculations with that number and test to perform logical tests on
  1037. it.
  1038.  
  1039. Sample Session:
  1040.  
  1041. ┌───────────────────────────────────────────────────────────────┐
  1042. │ $cat num_args                                                 │
  1043. │ echo 'This script was called with'                            │
  1044. │ echo $# 'arguments'                                           │
  1045. │ $num_args Richard Kathleen Douglas                            │
  1046. │ This script was called with                                   │
  1047. │ 3 arguments                                                   │
  1048. │ $                                                             │
  1049. └───────────────────────────────────────────────────────────────┘
  1050. 2.4.3  Shift
  1051.  
  1052. The shift command promotes each of the command-line arguments. 
  1053. The second argument, represented by $2, is now the first argument,
  1054. represented by $1.  The third becomes the second and so on until
  1055. the last argument becomes the next to last.  You can access only
  1056. the first nine command-line arguments (as $1 through $9).  The
  1057. shift command gives you access to the tenth, and the first becomes
  1058. unavailable.  There is no "unshift" command that will return the
  1059. arguments that are no longer available.
  1060.  
  1061. Sample Session: 
  1062.  
  1063. ┌───────────────────────────────────────────────────────────────┐
  1064. │ $cat demo_shift                                               │
  1065. │ echo 'arg1='$1 '  arg2='$2 '   arg3='$3                       │
  1066. │ shift                                                         │
  1067. │ echo 'arg1='$1 '  arg2='$2 '   arg3='$3                       │
  1068. │ shift                                                         │
  1069. │ echo 'arg1='$1 '  arg2='$2 '   arg3='$3                       │
  1070. │ shift                                                         │
  1071. │ echo 'arg1='$1 '  arg2='$2 '   arg3='$3                       │
  1072. │ shift                                                         │
  1073. │ $demo_shift Richard Kathleen Douglas                          │
  1074. │ arg1=Richard  arg2=Kathleen  arg3=Douglas                     │
  1075. │ arg1=Kathleen arg2=Douglas   arg3=                            │
  1076. │ arg1=Douglas  arg2=          arg3=                            │
  1077. │ demo_shift: cannot shift                                      │
  1078. │ $                                                             │
  1079. └───────────────────────────────────────────────────────────────┘
  1080.  
  1081. The BourneShell will display an error message when the script
  1082. executes a shift command after it has run out of variables.
  1083. 2.4.4  Set
  1084.  
  1085.  
  1086. The Set command will display a list of all the variables that are
  1087. set when it has no arguments.
  1088.  
  1089. Sample Session:
  1090.  
  1091. ┌───────────────────────────────────────────────────────────────┐
  1092. │ $set                                                          │
  1093. │ HOME=/user0/teacher                                           │
  1094. │ IFS=                                                          │
  1095. │                                                               │
  1096. │ LOGNAME=richard                                               │
  1097. │ MAIL=/usr/mail/richard                                        │
  1098. │ MAILCHECK=600                                                 │
  1099. │ PATH=:/bin:/usr/bin                                           │
  1100. │ PS1=$                                                         │
  1101. │ PS2=>                                                         │
  1102. │ SHELL=/bin/sh                                                 │
  1103. │ TERM=vt100                                                    │
  1104. │ TZ=MST7MDT                                                    │
  1105. │ $                                                             │
  1106. └───────────────────────────────────────────────────────────────┘
  1107.  
  1108. When set is called with arguments, it sets the value of the
  1109. command-line arguments ($1-$n) to the arguments.  The example sets
  1110. the first three arguments.
  1111.  
  1112. Sample Session:
  1113.  
  1114. ┌───────────────────────────────────────────────────────────────┐
  1115. │ $cat set_ex                                                   │
  1116. │ set who really cares                                          │
  1117. │ echo $#: $*                                                   │
  1118. │ $set_ex                                                       │
  1119. │ 3: who really cares                                           │
  1120. │ $                                                             │
  1121. └───────────────────────────────────────────────────────────────┘
  1122. 2.4.5  expr
  1123.  
  1124. The expr command will perform arithmetic in the BourneShell.
  1125.  
  1126. ╔═══════════════════════════════════════════════════════════════╗
  1127. ║   Command format:  expr expression                            ║
  1128. ║                                                               ║
  1129. ║   See Appendix C for a complete list of expressions           ║
  1130. ╚═══════════════════════════════════════════════════════════════╝
  1131.  
  1132. The arguments are taken as an expression. After the evaluation has
  1133. taken place, the result is written to standard output.  The terms
  1134. of the expression must be separated by blanks.  Special characters
  1135. to the shell must be escaped.  Strings containing blanks or other
  1136. special characters must be quoted.
  1137.  
  1138. Sample Session:
  1139.  
  1140. ┌───────────────────────────────────────────────────────────────┐
  1141. │ $expr 7 + 8 + 10                                              │
  1142. │ 25                                                            │
  1143. │ $expr 10 - 8                                                  │
  1144. │ 2                                                             │
  1145. │ $expr 10 '*' 4                                                │
  1146. │ 40                                                            │
  1147. │ $expr 135 / 5                                                 │
  1148. │ 27                                                            │
  1149. │ $                                                             │
  1150. └───────────────────────────────────────────────────────────────┘
  1151.  
  1152. expr will also work with user defined variables as in the following
  1153. example:
  1154.  
  1155. Sample Session:
  1156.  
  1157. ┌───────────────────────────────────────────────────────────────┐
  1158. │ $cat data                                                     │
  1159. │ 8                                                             │
  1160. │ 15                                                            │
  1161. │ 25                                                            │
  1162. │ $cat express                                                  │
  1163. │ count=0                                                       │
  1164. │ tot=0                                                         │
  1165. │ for a in `cat data`                                           │
  1166. │ do                                                            │
  1167. │ tot=`expr $tot + $a`                                          │
  1168. │ count=`expr $count + 1`                                       │
  1169. │ done                                                          │
  1170. │ avg=`expr $tot / $count`                                      │
  1171. │ echo "The average is $avg"                                    │
  1172. │ $                                                             │
  1173. └───────────────────────────────────────────────────────────────┘
  1174. Let's execute the script "express" with tracing on so we can follow
  1175. the execution.
  1176.  
  1177. Sample Session:
  1178.  
  1179. ┌───────────────────────────────────────────────────────────────┐
  1180. │ $sh -x express                                                │
  1181. │ count=0                                                       │
  1182. │ tot=0                                                         │
  1183. │ + cat data                                                    │
  1184. │ + expr 0 + 8                                                  │
  1185. │ tot=8                                                         │
  1186. │ + expr 0 + 1                                                  │
  1187. │ count=1                                                       │
  1188. │ + expr 8 + 15                                                 │
  1189. │ tot=23                                                        │
  1190. │ + expr 1 + 1                                                  │
  1191. │ count=2                                                       │
  1192. │ + expr 23 + 25                                                │
  1193. │ tot=48                                                        │
  1194. │ + expr 2 + 1                                                  │
  1195. │ count=3                                                       │
  1196. │ + expr 48 / 3                                                 │
  1197. │ avg=16                                                        │
  1198. │ + echo The average is 16                                      │
  1199. │ The average is 16                                             │
  1200. │ $                                                             │
  1201. └───────────────────────────────────────────────────────────────┘
  1202.                                NOTES
  1203. ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  1204.                                NOTES
  1205. ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  1206. Workshop 2
  1207.  
  1208. This workshop will reinforce your understanding of the ideas
  1209. presented in Chapter 2. Login to the Multimax using the username
  1210. and password given to you by the instructor.  Each student is to
  1211. complete the entire workshop.
  1212.  
  1213. DESK EXERCISES 
  1214.  
  1215.      1.   Any series of non-blank characters can be assigned to a
  1216.           user variable.
  1217.  
  1218.                             True/False
  1219.  
  1220.  
  1221.  
  1222.      2.   How can you insert a space into a user variable?
  1223.  
  1224.  
  1225.  
  1226.  
  1227.  
  1228.      3.   What utility can be used to display the contents of a
  1229.           user variable to standard output?
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.      4.   The backslash (\) character is used to remove the special
  1236.           meaning of some characters.
  1237.  
  1238.                             True/False
  1239.  
  1240.  
  1241.  
  1242.  
  1243.      5.   What other character can be used to prevent the shell
  1244.           from doing the substitution?
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250.      6.   Double quote marks will prevent the shell from making
  1251.           the substitution.
  1252.  
  1253.                             True/False
  1254.  
  1255.  
  1256.  
  1257.                      Continue on the next page
  1258.      7.   What do the following shell variables do?
  1259.  
  1260.  
  1261.           HOME
  1262.  
  1263.  
  1264.  
  1265.  
  1266.  
  1267.           IFS
  1268.  
  1269.  
  1270.  
  1271.  
  1272.           MAIL
  1273.  
  1274.  
  1275.  
  1276.  
  1277.  
  1278.           MAILPATH
  1279.  
  1280.  
  1281.  
  1282.  
  1283.  
  1284.           MAILCHECK
  1285.  
  1286.  
  1287.  
  1288.  
  1289.  
  1290.           PATH
  1291.  
  1292.  
  1293.  
  1294.  
  1295.  
  1296.           PS1
  1297.  
  1298.  
  1299.  
  1300.  
  1301.  
  1302.           PS2
  1303.  
  1304.  
  1305.  
  1306.  
  1307.  
  1308.  
  1309.                      Continue on the next page
  1310.      8.   What is the command to create a read-only user variable?
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.      9.   What is the read-only shell variable that represents the
  1318.           calling program?
  1319.  
  1320.  
  1321.  
  1322.  
  1323.  
  1324.  
  1325.      10.  What do $1,$2,...,$9 represent?
  1326.  
  1327.  
  1328.  
  1329.  
  1330.  
  1331.  
  1332.      11.  What BourneShell variable represents all of the command
  1333.           line arguments?
  1334.  
  1335.  
  1336.  
  1337.  
  1338.  
  1339.  
  1340.      12.  What does the shift command do?
  1341.  
  1342.  
  1343.  
  1344.  
  1345.  
  1346.  
  1347.      13.  What is displayed when you enter set with no arguments?
  1348.  
  1349.  
  1350.  
  1351.  
  1352.  
  1353.  
  1354.  
  1355.  
  1356.  
  1357.  
  1358.  
  1359.  
  1360.  
  1361.                      Continue on the next page
  1362. COMPUTER EXERCISES 
  1363.  
  1364.  
  1365.      14.  Login to the Multimax (domax1) using the username and
  1366.           password given to you by the instructor.
  1367.  
  1368.  
  1369.  
  1370.  
  1371.  
  1372.      15.  Create a subdirectory called sub_dir.
  1373.  
  1374.  
  1375.  
  1376.  
  1377.  
  1378.      16.  Modify your .profile to include the following:
  1379.  
  1380.  
  1381.           a) Change the home directory to sub_dir
  1382.  
  1383.           b) Set the internal-field separator to a comma
  1384.  
  1385.           c) Have mail messages saved into mail1.
  1386.  
  1387.           d) Set the PATH to look for programs in the following  
  1388.              directories:
  1389.  
  1390.                $HOME/bin
  1391.                /bin
  1392.                /usr/bin
  1393.  
  1394.           e) Change the prompt to reflect the name of the system
  1395.  
  1396.           f) Change the secondary prompt to 'More?'
  1397.  
  1398.  
  1399.  
  1400.  
  1401.  
  1402.      17.  Execute the .profile
  1403.           Enter $. .profile
  1404.  
  1405.  
  1406.  
  1407.  
  1408.      18.  Verify that the changes are correct. If you have extra
  1409.            time go to the next page.
  1410.  
  1411.  
  1412.  
  1413.                     Extra Mile on the next page
  1414. Extra Mile
  1415.  
  1416.  
  1417. Change the .profile file so the date/time and a list of all
  1418. users that are currently logged in will be displayed on your
  1419. monitor screen automatically when you login.
  1420.                                NOTES
  1421. ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  1422. 3.  POSITIONAL PARAMETERS
  1423.  
  1424.  
  1425. A BourneShell script can also read in command-line arguments.  
  1426. The first argument is referred to as $1, the second is $2, and so
  1427. on.  Command-line arguments are referred to as positional
  1428. parameters.
  1429.  
  1430. Let's look at an example BourneShell script to see how these are
  1431. used.
  1432.  
  1433. Sample Session:
  1434.  
  1435. ┌───────────────────────────────────────────────────────────────┐
  1436. │ $cat neat_shell                                               │
  1437. │ echo $1 $2 $3                                                 │
  1438. │ echo $0 is the name of the shell script                       │
  1439. │ echo "There were $# arguments."                               │
  1440. │ echo $*                                                       │
  1441. │ $                                                             │
  1442. └───────────────────────────────────────────────────────────────┘
  1443.  
  1444. Insure that the BourneShell script is executable by issuing this
  1445. command:
  1446.  
  1447. Sample Session:
  1448.  
  1449. ┌───────────────────────────────────────────────────────────────┐
  1450. │    $chmod a+x neat_shell                                      │
  1451. │    $                                                          │
  1452. └───────────────────────────────────────────────────────────────┘
  1453.  
  1454. Now, if we type the name of the BourneShell script with no
  1455. arguments, we get the following results.
  1456.  
  1457. Sample Session:
  1458.  
  1459. ┌───────────────────────────────────────────────────────────────┐
  1460. │ $neat_shell                                                   │
  1461. │                                                               │
  1462. │ neat_shell is the name of the shell script                    │
  1463. │ There were 0 arguments.                                       │
  1464. │                                                               │
  1465. │ $                                                             │
  1466. └───────────────────────────────────────────────────────────────┘
  1467.  
  1468. In this sample session, there were no arguments given so none were
  1469. printed.  $0 is the positional parameter that refers to the name
  1470. of the script.  Since there were no arguments given with this
  1471. invocation of neat_shell, there were zero arguments listed.      
  1472.                
  1473. 3.1  Reading Input Into a Shell Variable
  1474.  
  1475. The BourneShell script can read user input from standard input.  
  1476. The read command will read one line from standard input and assign
  1477. the line to one or more variables.  The following example shows how
  1478. this works.
  1479.  
  1480. Sample Session:
  1481.  
  1482. ┌───────────────────────────────────────────────────────────────┐
  1483. │ $cat read_script                                              │
  1484. │ echo "Please enter a string of your choice"                   │
  1485. │ read a                                                        │
  1486. │ echo $a                                                       │
  1487. │ $                                                             │
  1488. └───────────────────────────────────────────────────────────────┘
  1489.  
  1490. This simple script will read one line from standard input
  1491. (keyboard) and assign it to the variable a.
  1492.  
  1493. Sample Session:
  1494.  
  1495. ┌───────────────────────────────────────────────────────────────┐
  1496. │ $read_script                                                  │
  1497. │ Please enter a string of your choice                          │
  1498. │ Here it is                                                    │
  1499. │ Here it is                                                    │
  1500. │ $                                                             │
  1501. └───────────────────────────────────────────────────────────────┘
  1502.  
  1503. The line read from standard input can also be assigned to several
  1504. variables as shown in the following example.
  1505.  
  1506.  
  1507. Sample Session:
  1508.                                                   
  1509. ┌───────────────────────────────────────────────────────────────┐
  1510. │ $cat reads                                                    │
  1511. │ echo "Please enter three strings"                             │
  1512. │ read a b c                                                    │
  1513. │ echo $a $b $c                                                 │
  1514. │ echo $c                                                       │
  1515. │ echo $b                                                       │
  1516. │ echo $a                                                       │
  1517. │ $                                                             │
  1518. └───────────────────────────────────────────────────────────────┘
  1519.  
  1520. This time, we will turn on the trace mechanism and follow the
  1521. execution of this BourneShell script.
  1522.  
  1523. Sample Session:
  1524.  
  1525. ┌───────────────────────────────────────────────────────────────┐
  1526. │ $sh -x reads                                                  │
  1527. │ + echo Please enter three strings                             │
  1528. │ Please enter three strings                                    │
  1529. │ + read a b c                                                  │
  1530. │ this is more than three strings                               │
  1531. │ + echo this is more than three strings                        │
  1532. │ this is more than three strings                               │
  1533. │ + echo more than three strings                                │
  1534. │ more than three strings                                       │
  1535. │ + echo is                                                     │
  1536. │ is                                                            │
  1537. │ + echo this                                                   │
  1538. │ this                                                          │
  1539. │ $                                                             │
  1540. └───────────────────────────────────────────────────────────────┘
  1541.  
  1542. It is interesting to note that the spaces separate the values for
  1543. the variables a,b, and c.  For example, the variable a was assigned
  1544. the string this, the variable b was assigned the string is, and the
  1545. remainder of the line was assigned to c (including the spaces).
  1546.  
  1547. Sample Session:
  1548.                                                   
  1549. ┌───────────────────────────────────────────────────────────────┐
  1550. │ $cat read_ex                                                  │
  1551. │ echo  'Enter line: \c'                                        │
  1552. │ read line                                                     │
  1553. │ echo "The line was: $line"                                    │
  1554. │ $                                                             │
  1555. └───────────────────────────────────────────────────────────────┘
  1556.                                                                  
  1557. In this example, the \c option will suppress the carriage return.
  1558. The single quote marks protect the backslash from being interpreted
  1559. by the shell.  Also notice that the double quote marks have no
  1560. effect on the substitution of the variable line.                 
  1561.             
  1562. Sample Session:
  1563.  
  1564. ┌───────────────────────────────────────────────────────────────┐
  1565. │ $read_ex                                                      │
  1566. │ Enter line: All's well that ends well                         │
  1567. │ The line was: All's well that ends well                       │
  1568. │ $                                                             │
  1569. └───────────────────────────────────────────────────────────────┘
  1570. 3.2  Command Substitution
  1571.  
  1572. You can execute a command by enclosing it within two grave accent
  1573. marks [these are sometimes called backquotes (`)].  The BourneShell
  1574. will replace the command and the grave marks with the output from
  1575. the command.
  1576.  
  1577. Sample Session:
  1578.  
  1579. ┌───────────────────────────────────────────────────────────────┐
  1580. │ $cat dir                                                      │
  1581. │ dir=`pwd`                                                     │
  1582. │ echo 'You are using the' $dir 'directory'                     │
  1583. │ $                                                             │
  1584. └───────────────────────────────────────────────────────────────┘
  1585.                                                                  
  1586. NOTE:     The grave marks lean to the left, and the apostrophes 
  1587.           lean to the right.  The grave marks enclose the pwd  
  1588.           command.                                              
  1589.                                                                  
  1590. Sample Session:
  1591.  
  1592. ┌───────────────────────────────────────────────────────────────┐
  1593. │ $dir                                                          │
  1594. │ You are using the /user0/rharding directory                   │
  1595. │ $                                                             │
  1596. └───────────────────────────────────────────────────────────────┘
  1597.  
  1598. The important thing to notice here is that the pwd command was
  1599. executed; and the output, /user0/rharding, was then assigned to
  1600. the variable dir.
  1601.  
  1602. It is not necessary to assign the output of a command to a variable
  1603. as shown in the previous example.  The command substitution can
  1604. occur directly as shown in the next example.
  1605.  
  1606. Sample Session:
  1607.  
  1608. ┌───────────────────────────────────────────────────────────────┐
  1609. │ $cat dir2                                                     │
  1610. │ echo 'You are using the' `pwd` 'directory'                    │
  1611. │ $dir2                                                         │
  1612. │ You are using the /user0/rharding directory                   │
  1613. │ $                                                             │
  1614. └───────────────────────────────────────────────────────────────┘
  1615. One final example will show a practical use of command
  1616. substitution.  This BourneShell script will use the date command
  1617. to provide the date in a useful format.
  1618.  
  1619. The normal output from the date command looks like the following.
  1620.  
  1621. Sample Session:
  1622.  
  1623. ┌───────────────────────────────────────────────────────────────┐
  1624. │ $date                                                         │
  1625. │ Wed Sep 12 18:02:05 MDT 1990                                  │
  1626. │ $                                                             │
  1627. └───────────────────────────────────────────────────────────────┘
  1628.  
  1629. Here's a BourneShell script that rearranges the output into a more
  1630. useable format.
  1631.  
  1632. Sample Session:
  1633.  
  1634. ┌───────────────────────────────────────────────────────────────┐
  1635. │ $cat dateset                                                  │
  1636. │ set `date`                                                    │
  1637. │ echo $*                                                       │
  1638. │ echo                                                          │
  1639. │ echo 'Argument 1:' $1                                         │
  1640. │ echo 'Argument 2:' $2                                         │
  1641. │ echo 'Argument 3:' $3                                         │
  1642. │ echo 'Argument 4:' $4                                         │
  1643. │ echo                                                          │
  1644. │ echo $2 $3, $6                                                │
  1645. │ $dateset                                                      │
  1646. │ Wed Sep 12 18:02:05 MDT 1990                                  │
  1647. │                                                               │
  1648. │ Argument 1: Wed                                               │
  1649. │ Argument 2: Sep                                               │
  1650. │ Argument 3: 12                                                │
  1651. │ Argument 4: 18:02:05                                          │
  1652. │                                                               │
  1653. │ Sep 12, 1990                                                  │
  1654. │ $                                                             │
  1655. └───────────────────────────────────────────────────────────────┘
  1656.  
  1657. The first command in the BourneShell script dateset uses the grave
  1658. accent marks to set the command-line argument variables to the
  1659. output of the date command.  The next commands show the first four
  1660. of these argument variables.  The final command displays the
  1661. arguments in a different order that could be useful in a report or
  1662. a letter.
  1663. 3.3  Comments in BourneShell Scripts
  1664.  
  1665.  
  1666. Comments can be inserted into the BourneShell script by beginning
  1667. each comment line with the pound symbol (#) or a colon (:).  All
  1668. characters after the comment character will be ignored by the
  1669. shell.  The only exception to this rule is that the first character
  1670. of the first line must not be a pound symbol; if the first
  1671. character is a pound sign, the BourneShell tries to execute the
  1672. script as if it was written in CShell syntax.
  1673.  
  1674. Sample Session:
  1675.  
  1676. ┌───────────────────────────────────────────────────────────────┐
  1677. │ $cat com_sub                                                  │
  1678. │   #   The first line sets your present working directory      │
  1679. │ #     to the variable 'directory'                             │
  1680. │ directory=`pwd`                                               │
  1681. │ #     The second line sets the date to the variable 'when'    │
  1682. │ when=`date`                                                   │
  1683. │ :     The third line will echo on the screen                  │
  1684. │ echo "You are in $directory on $when"                         │
  1685. │ :     You could have said echo :                              │
  1686. │ :        "You are in `pwd` on `date`"                         │
  1687. │ :     to have a one line program                              │
  1688. │ $                                                             │
  1689. └───────────────────────────────────────────────────────────────┘
  1690.                                                                
  1691. 3.4  BourneShell Environment - Exporting Variables
  1692.  
  1693. Within a process, you can declare, initialize, read, and modify
  1694. variables.  The variable is local to that process.  When a process
  1695. forks a child process, the parent process does not automatically
  1696. pass the value of the variable to the child process.
  1697.  
  1698. Here is an example of the variables not being exported.
  1699.  
  1700. Sample Session:
  1701.  
  1702. ┌───────────────────────────────────────────────────────────────┐
  1703. │ $cat no_export                                                │
  1704. │ car=mercedes       # set the variable                         │
  1705. │ echo $0 $car $$    # $0 = name of file executed               │
  1706. │                    # $car =value of variable car              │
  1707. │                    # $$ = PID number (process id)             │
  1708. │ inner              # execute another BourneShell script       │
  1709. │ echo $0 $car $$    # display same as above                    │
  1710. │ $cat inner                                                    │
  1711. │ echo $0 $car $$    # display variables for this process       │
  1712. │ $chmod a+x no_export                                          │
  1713. │ $chmod a+x inner                                              │
  1714. │ $no_export                                                    │
  1715. │ no_export mercedes 4790                                       │
  1716. │ inner 4792                                                    │
  1717. │ no_export mercedes 4790                                       │
  1718. │ $                                                             │
  1719. └───────────────────────────────────────────────────────────────┘
  1720.  
  1721. When no_export was executed, it, of course, assigned a value of
  1722. mercedes to the variable car and printed it out.  The call to inner
  1723. created a child process.  Its PID is 4792, while the parent PID is
  1724. 4790.  Notice, when inner tried to print the value of car, it
  1725. printed nothing.  The reason is because the value of car was not
  1726. passed by the parent.
  1727. Can the value be passed from parent to child process?  Yes, by
  1728. using the export command.  Let's look at an example.
  1729.  
  1730. Sample Session:
  1731.  
  1732. ┌───────────────────────────────────────────────────────────────┐
  1733. │ $cat export_it                                                │
  1734. │ car=mercedes                                                  │
  1735. │ export car                                                    │
  1736. │ echo $0 $car $$                                               │
  1737. │ inner1                                                        │
  1738. │ echo $0 $car $$                                               │
  1739. │ $cat inner1                                                   │
  1740. │ echo $0 $car $$                                               │
  1741. │ car=chevy                                                     │
  1742. │ echo $0 $car $$