33
34 echo; echo "Done copying $OF to CDR on device $CDROM."
35
36 echo "Do you want to erase the image file (y/n)? " # Probably a huge file.
37 read answer
38
39 case "$answer" in
40 [yY]) rm -f $OF
41 echo "$OF erased."
42 ;;
43 *) echo "$OF not erased.";;
44 esac
45
46 echo
47
48 # Exercise:
49 # Change the above "case" statement to also accept "yes" and "Yes" as input.
50
51 exit 0
例子 A-6. Collatz序列
1 #!/bin/bash
2 # collatz.sh
3
4 # The notorious "hailstone" or Collatz series.
5 # -------------------------------------------
6 # 1) Get the integer "seed" from the command line.
7 # 2) NUMBER
8 # 3) Print NUMBER.
9 # 4) If NUMBER is even, divide by 2, or
10 # 5)+ if odd, multiply by 3 and add 1.
11 # 6) NUMBER
12 # 7) Loop back to step 3 (for specified number of iterations).
13 #
14 # The theory is that every sequence,
15 #+ no matter how large the initial value,
16 #+ eventually settles down to repeating "4,2,1..." cycles,
17 #+ even after fluctuating through a wide range of values.
18 #
19 # This is an instance of an "iterate",
20 #+ an operation that feeds its output back into the input.
21 # Sometimes the result is a "chaotic" series.
22
23
24 MAX_ITERATIONS=200
25 # For large seed numbers (>32000), increase MAX_ITERATIONS.
26
27 h=${1:-$$} # Seed
28 # Use $PID as seed,
29 #+ if not specified as command-line arg.
30
31 echo
32 echo "C($h) --- $MAX_ITERATIONS Iterations"
33 echo
34
35 for ((i=1; i<=MAX_ITERATIONS; i++))
36 do
37
38 echo -n "$h "
39 # ^^^^^
40 # tab
41
42 let "remainder = h % 2"
43 if [ "$remainder" -eq 0 ] # Even?
44 then
45 let "h /= 2" # Divide by 2.
46 else
47 let "h = h*3 + 1" # Multiply by 3 and add 1.
48 fi
49
50
51 COLUMNS=10 # Output 10 values per line.
52 let "line_break = i % $COLUMNS"
53 if [ "$line_break" -eq 0 ]
54 then
55 echo
56 fi
57
58 done
59
60 echo
61
62 # For more information on this mathematical function,
63 #+ see "Computers, Pattern, Chaos, and Beauty", by Pickover, p. 185 ff.,
64 #+ as listed in the bibliography.
65
66 exit 0
例子 A-7. days-between: 计算两个日期之间天数差
1 #!/bin/bash
2 # days-between.sh: Number of days between two dates.
3 # Usage: ./days-between.sh [M]M/[D]D/YYYY [M]M/[D]D/YYYY
4 #
5 # Note: Script modified to account for changes in Bash 2.05b
6 #+ that closed the loophole permitting large negative
7 #+ integer return values.
8
9 ARGS=2 # Two command line parameters expected.
10 E_PARAM_ERR=65 # Param error.
11
12 REFYR=1600 # Reference year.
13 CENTURY=100
14 DIY=365
15 ADJ_DIY=367 # Adjusted for leap year + fraction.
16 MIY=12
17 DIM=31
18 LEAPCYCLE=4
19
20 MAXRETVAL=255 # Largest permissable
21 #+ positive return value from a function.
22
23 diff= # Declare global variable for date difference.
24 value= # Declare global variable for absolute value.
25 day= # Declare globals for day, month, year.
26 month=
27 year=
28
29
30 Param_Error () # Command line parameters wrong.
31 {
32 echo "Usage: `basename $0` [M]M/[D]D/YYYY [M]M/[D]D/YYYY"
33 echo " (date must be after 1/3/1600)"
34 exit $E_PARAM_ERR
35 }
36
37
38 Parse_Date () # Parse date from command line params.
39 {
40 month=${1%%}
43 let "year = `basename $1`" # Not a filename, but works just the same.
44 }
45
46
47 check_date () # Checks for invalid date(s) passed.
48 {
49 [ "$day" -gt "$DIM" ] || [ "$month" -gt "$MIY" ] || [ "$year" -lt "$REFYR" ] && Param_Error
50 # Exit script on bad value(s).
51 # Uses "or-list / and-list".
52 #
53 # Exercise: Implement more rigorous date checking.
54 }
55
56
57 strip_leading_zero () # Better to strip possible leading zero(s)
58 { #+ from day and/or month
59 return ${1#0} #+ since otherwise Bash will interpret them
60 } #+ as octal values (POSIX.2, sect 2.9.2.1).
61
62
63 day_index () # Gauss' Formula:
64 { # Days from Jan. 3, 1600 to date passed as param.
65
66 day=$1
67 month=$2
68 year=$3
69
70 let "month = $month - 2"
71 if [ "$month" -le 0 ]
72 then
73 let "month += 12"
74 let "year -= 1"
75 fi
76
77 let "year -= $REFYR"
78 let "indexyr = $year / $CENTURY"
79
80
81 let "Days = $DIY*$year + $year/$LEAPCYCLE - $indexyr + $indexyr/$LEAPCYCLE + $ADJ_DIY*$month/$MIY + $day - $DIM"
82 # For an in-depth explanation of this algorithm, see
83 #+ http://home.t-online.de/home/berndt.schwerdtfeger/cal.htm
84
85
86 echo $Days
87
88 }
89
90
91 calculate_difference () # Difference between to day indices.
92 {
93 let "diff = $1 - $2" # Global variable.
94 }
95
96
97 abs () # Absolute value
98 { # Uses global "value" variable.
99 if [ "$1" -lt 0 ] # If negative
100 then #+ then
101 let "value = 0 - $1" #+ change sign,
102 else #+ else
103 let "value = $1" #+ leave it alone.
104 fi
105 }
106
107
108
109 if [ $# -ne "$ARGS" ] # Require two command line params.
110 then
111 Param_Error
112 fi
113
114 Parse_Date $1
115 check_date $day $month $year # See if valid date.
116
117 strip_leading_zero $day # Remove any leading zeroes
118 day=$? #+ on day and/or month.
119 strip_leading_zero $month
120 month=$?
121
122 let "date1 = `day_index $day $month $year`"
123
124
125 Parse_Date $2
126 check_date $day $month $year
127
128 strip_leading_zero $day
129 day=$?
130 strip_leading_zero $month
131 month=$?
132
133 date2=$(day_index $day $month $year) # Command substitution.
134
135
136 calculate_difference $date1 $date2
137
138 abs $diff # Make sure it's positive.
139 diff=$value
140
141 echo $diff
142
143 exit 0
144 # Compare this script with
145 #+ the implementation of Gauss' Formula in a C program at:
146 #+ http://buschencrew.hypermart.net/software/datedif
例子 A-8. 构造一个"字典"
1 #!/bin/bash
2 # makedict.sh [make dictionary]
3
4 # Modification of /usr/sbin/mkdict script.
5 # Original script copyright 1993, by Alec Muffett.
6 #
7 # This modified script included in this document in a manner
8 #+ consistent with the "LICENSE" document of the "Crack" package
9 #+ that the original script is a part of.