- •Table of Contents
- •Chapter 1. Why Shell Programming?
- •2.1. Invoking the script
- •2.2. Preliminary Exercises
- •Part 2. Basics
- •Chapter 3. Exit and Exit Status
- •Chapter 4. Special Characters
- •Chapter 5. Introduction to Variables and Parameters
- •5.1. Variable Substitution
- •5.2. Variable Assignment
- •5.3. Bash Variables Are Untyped
- •5.4. Special Variable Types
- •Chapter 6. Quoting
- •Chapter 7. Tests
- •7.1. Test Constructs
- •7.2. File test operators
- •7.3. Comparison operators (binary)
- •7.4. Nested if/then Condition Tests
- •7.5. Testing Your Knowledge of Tests
- •Chapter 8. Operations and Related Topics
- •8.1. Operators
- •8.2. Numerical Constants
- •Part 3. Beyond the Basics
- •Chapter 9. Variables Revisited
- •9.1. Internal Variables
- •9.2. Manipulating Strings
- •9.2.1. Manipulating strings using awk
- •9.2.2. Further Discussion
- •9.3. Parameter Substitution
- •9.4. Typing variables: declare or typeset
- •9.5. Indirect References to Variables
- •9.6. $RANDOM: generate random integer
- •9.7. The Double Parentheses Construct
- •Chapter 10. Loops and Branches
- •10.1. Loops
- •10.2. Nested Loops
- •10.3. Loop Control
- •10.4. Testing and Branching
- •Chapter 11. Internal Commands and Builtins
- •11.1. Job Control Commands
- •Chapter 12. External Filters, Programs and Commands
- •12.1. Basic Commands
- •12.2. Complex Commands
- •12.3. Time / Date Commands
- •12.4. Text Processing Commands
- •12.5. File and Archiving Commands
- •12.6. Communications Commands
- •12.7. Terminal Control Commands
- •12.8. Math Commands
- •12.9. Miscellaneous Commands
- •Chapter 13. System and Administrative Commands
- •Chapter 14. Command Substitution
- •Chapter 15. Arithmetic Expansion
- •Chapter 16. I/O Redirection
- •16.1. Using exec
- •16.2. Redirecting Code Blocks
- •16.3. Applications
- •Chapter 17. Here Documents
- •Chapter 18. Recess Time
- •Part 4. Advanced Topics
- •Chapter 19. Regular Expressions
- •19.1. A Brief Introduction to Regular Expressions
- •19.2. Globbing
- •Chapter 20. Subshells
- •Chapter 21. Restricted Shells
- •Chapter 22. Process Substitution
- •Chapter 23. Functions
- •23.1. Complex Functions and Function Complexities
- •23.2. Local Variables
- •23.2.1. Local variables make recursion possible.
- •Chapter 24. Aliases
- •Chapter 25. List Constructs
- •Chapter 26. Arrays
- •Chapter 27. Files
- •Chapter 28. /dev and /proc
- •28.2. /proc
- •Chapter 29. Of Zeros and Nulls
- •Chapter 30. Debugging
- •Chapter 31. Options
- •Chapter 32. Gotchas
- •Chapter 33. Scripting With Style
- •33.1. Unofficial Shell Scripting Stylesheet
- •Chapter 34. Miscellany
- •34.2. Shell Wrappers
- •34.3. Tests and Comparisons: Alternatives
- •34.4. Optimizations
- •34.5. Assorted Tips
- •34.6. Oddities
- •34.7. Portability Issues
- •34.8. Shell Scripting Under Windows
- •Chapter 35. Bash, version 2
- •Chapter 36. Endnotes
- •36.1. Author's Note
- •36.2. About the Author
- •36.3. Tools Used to Produce This Book
- •36.3.1. Hardware
- •36.3.2. Software and Printware
- •36.4. Credits
- •Bibliography
- •Appendix A. Contributed Scripts
- •Appendix C. Exit Codes With Special Meanings
- •Appendix D. A Detailed Introduction to I/O and I/O Redirection
- •Appendix E. Localization
- •Appendix F. History Commands
- •Appendix G. A Sample .bashrc File
- •Appendix H. Converting DOS Batch Files to Shell Scripts
- •Appendix I. Exercises
- •Appendix J. Copyright
Advanced Bash−Scripting Guide
The /dev/urandom device−file provides a means of generating much more
"random" pseudorandom numbers than the $RANDOM variable. dd if=/dev/urandom of=targetfile bs=1 count=XX creates a file of well−scattered pseudorandom numbers. However, assigning these numbers to a variable in a script requires a workaround, such as filtering through od (as in above example) or using dd (see Example 12−34).
There are also other means of generating pseudorandom numbers in a script. Awk provides a convenient means of doing this.
Example 9−23. Pseudorandom numbers, using awk
#!/bin/bash
#random2.sh: Returns a pseudorandom number in the range 0 − 1.
#Uses the awk rand() function.
AWKSCRIPT=' { srand(); print rand() } '
#Command(s) / parameters passed to awk
#Note that srand() reseeds awk's random number generator.
echo −n "Random number between 0 and 1 = " echo | awk "$AWKSCRIPT"
exit 0
#Exercises for the reader:
#−−−−−−−−−−−−−−−−−−−−−−−−−
#1] Using a loop construct, print out 10 different random numbers.
#(Hint: you must reseed the "srand()" function with a different seed
#in each pass through the loop. What happens if you fail to do this?)
#2] Using an integer multiplier as a scaling factor, generate random numbers
#in the range between 10 and 100.
#3] Same as exercise #2, above, but generate random integers this time.
9.7.The Double Parentheses Construct
Similar to the let command, the ((...)) construct permits arithmetic expansion and evaluation. In its simplest form, a=$(( 5 + 3 )) would set "a" to "5 + 3", or 8. However, this double parentheses construct is also a mechanism for allowing C−type manipulation of variables in Bash.
Example 9−24. C−type manipulation of variables
#!/bin/bash
# Manipulating a variable, C−style, using the ((...)) construct.
echo
9.7. The Double Parentheses Construct |
96 |
|
|
|
Advanced Bash−Scripting Guide |
(( a = 23 )) |
# Setting |
a value, C−style, with spaces on both sides of the "=". |
|
echo "a (initial value) |
= $a" |
||
(( a++ )) |
# Post−increment 'a', C−style. |
||
echo "a (after a++) = |
$a" |
||
(( a−− )) |
# Post−decrement 'a', C−style. |
||
echo "a (after a−−) = |
$a" |
||
(( ++a )) |
# Pre−increment 'a', C−style. |
||
echo "a (after ++a) = |
$a" |
||
(( −−a )) |
# Pre−decrement 'a', C−style. |
||
echo "a (after −−a) = |
$a" |
||
echo |
|
|
|
(( t = a<45?7:11 )) |
# C−style trinary operator. |
||
echo "If a < 45, then |
t = 7, else t = 11." |
||
echo "t = $t " |
|
# Yes! |
echo
#−−−−−−−−−−−−−−−−−
#Easter Egg alert!
#−−−−−−−−−−−−−−−−−
#Chet Ramey apparently snuck a bunch of undocumented C−style constructs #+ into Bash (actually adapted from ksh, pretty much).
#In the Bash docs, Ramey calls ((...)) shell arithmetic,
#+ but it goes far beyond that.
#Sorry, Chet, the secret is now out.
#See also "for" and "while" loops using the ((...)) construct.
#These work only with Bash, version 2.04 or later.
exit 0
See also Example 10−11.
9.7. The Double Parentheses Construct |
97 |