📄 contributed-scripts.html
字号:
279 echo "Generation $generation - $alive alive" 280 281 if [ "$alive" -eq 0 ] 282 then 283 echo 284 echo "Premature exit: no more cells alive!" 285 exit $NONE_ALIVE # No point in continuing 286 fi #+ if no live cells. 287 288 } 289 290 291 # ========================================================= 292 293 # main () 294 295 # Load initial array with contents of startup file. 296 initial=( `cat "$startfile" | sed -e '/#/d' | tr -d '\n' |\ 297 sed -e 's/\./\. /g' -e 's/_/_ /g'` ) 298 # Delete lines containing '#' comment character. 299 # Remove linefeeds and insert space between elements. 300 301 clear # Clear screen. 302 303 echo # Title 304 echo "=======================" 305 echo " $GENERATIONS generations" 306 echo " of" 307 echo "\"Life in the Slow Lane\"" 308 echo "=======================" 309 310 311 # -------- Display first generation. -------- 312 Gen0=`echo ${initial[@]}` 313 display "$Gen0" # Display only. 314 echo; echo 315 echo "Generation $generation - $alive alive" 316 # ------------------------------------------- 317 318 319 let "generation += 1" # Increment generation count. 320 echo 321 322 # ------- Display second generation. ------- 323 Cur=`echo ${initial[@]}` 324 next_gen "$Cur" # Update & display. 325 # ------------------------------------------ 326 327 let "generation += 1" # Increment generation count. 328 329 # ------ Main loop for displaying subsequent generations ------ 330 while [ "$generation" -le "$GENERATIONS" ] 331 do 332 Cur="$avar" 333 next_gen "$Cur" 334 let "generation += 1" 335 done 336 # ============================================================== 337 338 echo 339 340 exit 0 341 342 # -------------------------------------------------------------- 343 344 # The grid in this script has a "boundary problem." 345 # The the top, bottom, and sides border on a void of dead cells. 346 # Exercise: Change the script to have the grid wrap around, 347 # + so that the left and right sides will "touch," 348 # + as will the top and bottom. 349 # 350 # Exercise: Create a new "gen0" file to seed this script. 351 # Use a 12 x 16 grid, instead of the original 10 x 10 one. 352 # Make the necessary changes to the script, 353 #+ so it will run with the altered file. 354 # 355 # Exercise: Modify this script so that it can determine the grid size 356 #+ from the "gen0" file, and set any variables necessary 357 #+ for the script to run. 358 # This would make unnecessary any changes to variables 359 #+ in the script for an altered grid size.</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="GEN0DATA"></A><P><B>Example A-11. Data file for <SPANCLASS="QUOTE">"Game of Life"</SPAN></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 # This is an example "generation 0" start-up file for "life.sh". 2 # -------------------------------------------------------------- 3 # The "gen0" file is a 10 x 10 grid using a period (.) for live cells, 4 #+ and an underscore (_) for dead ones. We cannot simply use spaces 5 #+ for dead cells in this file because of a peculiarity in Bash arrays. 6 # [Exercise for the reader: explain this.] 7 # 8 # Lines beginning with a '#' are comments, and the script ignores them. 9 __.__..___ 10 ___._.____ 11 ____.___.. 12 _._______. 13 ____._____ 14 ..__...___ 15 ____._____ 16 ___...____ 17 __.._..___ 18 _..___..__</PRE></TD></TR></TABLE><HR></DIV><P>+++</P><P>The following two scripts are by Mark Moraes of the University of Toronto. See the enclosed file <SPANCLASS="QUOTE">"Moraes-COPYRIGHT"</SPAN> for permissions and restrictions.</P><DIVCLASS="EXAMPLE"><HR><ANAME="BEHEAD"></A><P><B>Example A-12. <BCLASS="COMMAND">behead</B>: Removing mail and news message headers </B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #! /bin/sh 2 # Strips off the header from a mail/News message i.e. till the first 3 # empty line 4 # Mark Moraes, University of Toronto 5 6 # ==> These comments added by author of this document. 7 8 if [ $# -eq 0 ]; then 9 # ==> If no command line args present, then works on file redirected to stdin. 10 sed -e '1,/^$/d' -e '/^[ ]*$/d' 11 # --> Delete empty lines and all lines until 12 # --> first one beginning with white space. 13 else 14 # ==> If command line args present, then work on files named. 15 for i do 16 sed -e '1,/^$/d' -e '/^[ ]*$/d' $i 17 # --> Ditto, as above. 18 done 19 fi 20 21 # ==> Exercise: Add error checking and other options. 22 # ==> 23 # ==> Note that the small sed script repeats, except for the arg passed. 24 # ==> Does it make sense to embed it in a function? Why or why not?</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="FTPGET"></A><P><B>Example A-13. <BCLASS="COMMAND">ftpget</B>: Downloading files via ftp </B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #! /bin/sh 2 # $Id: ftpget,v 1.2 91/05/07 21:15:43 moraes Exp $ 3 # Script to perform batch anonymous ftp. Essentially converts a list of 4 # of command line arguments into input to ftp. 5 # ==> This script is nothing but a shell wrapper around "ftp" . . . 6 # Simple, and quick - written as a companion to ftplist 7 # -h specifies the remote host (default prep.ai.mit.edu) 8 # -d specifies the remote directory to cd to - you can provide a sequence 9 # of -d options - they will be cd'ed to in turn. If the paths are relative, 10 # make sure you get the sequence right. Be careful with relative paths - 11 # there are far too many symlinks nowadays. 12 # (default is the ftp login directory) 13 # -v turns on the verbose option of ftp, and shows all responses from the 14 # ftp server. 15 # -f remotefile[:localfile] gets the remote file into localfile 16 # -m pattern does an mget with the specified pattern. Remember to quote 17 # shell characters. 18 # -c does a local cd to the specified directory 19 # For example, 20 # ftpget -h expo.lcs.mit.edu -d contrib -f xplaces.shar:xplaces.sh \ 21 # -d ../pub/R3/fixes -c ~/fixes -m 'fix*' 22 # will get xplaces.shar from ~ftp/contrib on expo.lcs.mit.edu, and put it in 23 # xplaces.sh in the current working directory, and get all fixes from 24 # ~ftp/pub/R3/fixes and put them in the ~/fixes directory. 25 # Obviously, the sequence of the options is important, since the equivalent 26 # commands are executed by ftp in corresponding order 27 # 28 # Mark Moraes <moraes@csri.toronto.edu>, Feb 1, 1989 29 # 30 31 32 # ==> These comments added by author of this document. 33 34 # PATH=/local/bin:/usr/ucb:/usr/bin:/bin 35 # export PATH 36 # ==> Above 2 lines from original script probably superfluous. 37 38 E_BADARGS=65 39 40 TMPFILE=/tmp/ftp.$$ 41 # ==> Creates temp file, using process id of script ($$) 42 # ==> to construct filename. 43 44 SITE=`domainname`.toronto.edu 45 # ==> 'domainname' similar to 'hostname' 46 # ==> May rewrite this to parameterize this for general use. 47 48 usage="Usage: $0 [-h remotehost] [-d remotedirectory]... [-f remfile:localfile]... \ 49 [-c localdirectory] [-m filepattern] [-v]" 50 ftpflags="-i -n" 51 verbflag= 52 set -f # So we can use globbing in -m 53 set x `getopt vh:d:c:m:f: $*` 54 if [ $? != 0 ]; then 55 echo $usage 56 exit $E_BADARGS 57 fi 58 shift 59 trap 'rm -f ${TMPFILE} ; exit' 0 1 2 3 15 60 # ==> Delete tempfile in case of abnormal exit from script. 61 echo "user anonymous ${USER-gnu}@${SITE} > ${TMPFILE}" 62 # ==> Added quotes (recommended in complex echoes). 63 echo binary >> ${TMPFILE} 64 for i in $* # ==> Parse command line args. 65 do 66 case $i in 67 -v) verbflag=-v; echo hash >> ${TMPFILE}; shift;; 68 -h) remhost=$2; shift 2;; 69 -d) echo cd $2 >> ${TMPFILE}; 70 if [ x${verbflag} != x ]; then 71 echo pwd >> ${TMPFILE}; 72 fi; 73 shift 2;; 74 -c) echo lcd $2 >> ${TMPFILE}; shift 2;; 75 -m) echo mget "$2" >> ${TMPFILE}; shift 2;; 76 -f) f1=`expr "$2" : "\([^:]*\).*"`; f2=`expr "$2" : "[^:]*:\(.*\)"`; 77 echo get ${f1} ${f2} >> ${TMPFILE}; shift 2;; 78 --) shift; break;; 79 esac 80 # ==> 'lcd' and 'mget' are ftp commands. See "man ftp" . . . 81 done 82 if [ $# -ne 0 ]; then 83 echo $usage 84 exit $E_BADARGS 85 # ==> Changed from "exit 2" to conform with style standard. 86 fi 87 if [ x${verbflag} != x ]; then 88 ftpflags="${ftpflags} -v" 89 fi 90 if [ x${remhost} = x ]; then 91 remhost=prep.ai.mit.edu 92 # ==> Change to match appropriate ftp site. 93 fi 94 echo quit >> ${TMPFILE} 95 # ==> All commands saved in tempfile. 96 97 ftp ${ftpflags} ${remhost} < ${TMPFILE} 98 # ==> Now, tempfile batch processed by ftp. 99 100 rm -f ${TMPFILE} 101 # ==> Finally, tempfile deleted (you may wish to copy it to a logfile). 102 103 104 # ==> Exercises: 105 # ==> --------- 106 # ==> 1) Add error checking. 107 # ==> 2) Add bells & whistles.</PRE></TD></TR></TABLE><HR></DIV><P>+</P><P>Antek Sawicki contributed the following script, which makes very clever use of the parameter substitution operators discussed in <AHREF="parameter-substitution.html">Section 9.3</A>.</P><DIVCLASS="EXAMPLE"><HR><ANAME="PW"></A><P><B>Example A-14. <BCLASS="COMMAND">password</B>: Generating random 8-character passwords</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # May need to be invoked with #!/bin/bash2 on older machines. 3 # 4 # Random password generator for Bash 2.x by Antek Sawicki <tenox@tenox.tc>, 5 # who generously gave permission to the document author to use it here. 6 # 7 # ==> Comments added by document author ==> 8 9 10 MATRIX="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 11 # ==> Password will consist of alphanumeric characters. 12 LENGTH="8" 13 # ==> May change 'LENGTH' for longer password. 14 15 16 while [ "${n:=1}" -le "$LENGTH" ] 17 # ==> Recall that := is "default substitution" operator. 18 # ==> So, if 'n' has not been initialized, set it to 1. 19 do 20 PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}" 21 # ==> Very clever, but tricky. 22 23 # ==> Starting from the innermost nesting... 24 # ==> ${#MATRIX} returns length of array MATRIX. 25 26 # ==> $RANDOM%${#MATRIX} returns random number between 1 27 # ==> and [length of MATRIX] - 1. 28 29 # ==> ${MATRIX:$(($RANDOM%${#MATRIX})):1} 30 # ==> returns expansion of MATRIX at random position, by length 1. 31 # ==> See {var:pos:len} parameter substitution in Chapter 9. 32 # ==> and the associated examples. 33 34 # ==> PASS=... simply pastes this result onto previous PASS (concatenation). 35 36 # ==> To visualize this more clearly, uncomment the following line 37 # echo "$PASS" 38 # ==> to see PASS being built up, 39 # ==> one character at a time, each iteration of the loop. 40 41 let n+=1 42 # ==> Increment 'n' for next pass. 43 done 44 45 echo "$PASS" # ==> Or, redirect to a file, as desired. 46 47 exit 0</PRE></TD></TR></TABLE><HR></DIV><P>+</P><P><ANAME="ZFIFO"></A>James R. Van Zandt contributed this script, which uses named pipes and, in his words, <SPANCLASS="QUOTE">"really exercises quoting and escaping"</SPAN>.</P><DIVCLASS="EXAMPLE"><HR><ANAME="FIFO"></A><P
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -