- •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
Chapter 22. Process Substitution
Process substitution is the counterpart to command substitution. Command substitution sets a variable to the result of a command, as in dir_contents=`ls −al` or xref=$( grep word datafile). Process substitution feeds the output of a process to another process (in other words, it sends the results of a command to another command).
Command substitution template
command within parentheses
>(command)
<(command)
These initiate process substitution. This uses /dev/fd/<n> files to send the results of the process within parentheses to another process. [49]
There is no space between the the "<" or ">" and the parentheses. Space there would give an error message.
bash$ echo >(true)
/dev/fd/63
bash$ echo <(true)
/dev/fd/63
Bash creates a pipe with two file descriptors, −−fIn and fOut−−. The stdin of true connects to fOut (dup2(fOut, 0)), then Bash passes a /dev/fd/fIn argument to echo. On systems lacking /dev/fd/<n> files, Bash may use temporary files. (Thanks, S.C.)
cat <(ls −l) |
|
# Same as |
ls −l | cat |
sort −k 9 <(ls −l /bin) <(ls −l /usr/bin) <(ls −l /usr/X11R6/bin)
#Lists all the files in the 3 main 'bin' directories, and sorts by filename.
#Note that three (count 'em) distinct commands are fed to 'sort'.
diff <(command1) <(command2) |
# Gives difference in command output. |
tar cf >(bzip2 −c > file.tar.bz2) dir
#Calls "tar cf /dev/fd/?? dir", and "bzip2 −c > file.tar.bz2".
#Because of the /dev/fd/<n> system feature,
#the pipe between both commands does not need to be named.
#
# This can be emulated.
#
bzip2 −c < pipe > file.tar.bz2& tar cf pipe dir
rm pipe
Chapter 22. Process Substitution |
243 |
Advanced Bash−Scripting Guide
#or
exec 3>&1
tar cf /dev/fd/4 dir 4>&1 >&3 3>&− | bzip2 −c > file.tar.bz2 3>&− exec 3>&−
#Thanks, S.C.
A reader of this document sent in the following interesting example of process substitution.
# Script fragment taken from SuSE distribution:
while read des what mask iface; do
#Some commands ...
done < <(route −n)
#To test it, let's make it do something. while read des what mask iface; do
echo $des $what $mask $iface done < <(route −n)
#Output:
#Kernel IP routing table
#Destination Gateway Genmask Flags Metric Ref Use Iface
#127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
#As S.C. points out, an easier−to−understand equivalent is: route −n |
while read des what |
mask iface; do |
# Variables set from output of pipe. |
echo $des $what $mask $iface |
|
|
done # Same output |
as above. |
|
|
|
|
Chapter 22. Process Substitution |
244 |