| Preface |
|
xiii | |
| 1 Beginning bash |
|
1 | (32) |
|
|
|
2 | (1) |
|
|
|
3 | (1) |
|
|
|
4 | (1) |
|
1.4 Showing Where You Are |
|
|
5 | (1) |
|
1.5 Finding and Running Commands |
|
|
6 | (2) |
|
1.6 Getting Information About Files |
|
|
8 | (3) |
|
1.7 Showing All Hidden (Dot) Files in the Current Directory |
|
|
11 | (2) |
|
|
|
13 | (2) |
|
1.9 Using or Replacing Builtins and External Commands |
|
|
15 | (2) |
|
1.10 Determining if You Are Running Interactively |
|
|
17 | (1) |
|
1.11 Setting bash as Your Default Shell |
|
|
18 | (2) |
|
1.12 Keeping bash Updated |
|
|
20 | (1) |
|
1.13 Getting bash for Linux |
|
|
21 | (1) |
|
1.14 Getting bash for xBSD |
|
|
22 | (2) |
|
1.15 Getting bash for macOS |
|
|
24 | (1) |
|
1.16 Getting bash for Unix |
|
|
24 | (2) |
|
1.17 Getting bash for Windows |
|
|
26 | (3) |
|
1.18 Getting bash Without Getting bash |
|
|
29 | (1) |
|
1.19 Learning More About bash Documentation |
|
|
30 | (3) |
| 2 Standard Output |
|
33 | (30) |
|
2.1 Writing Output to the Terminal/Window |
|
|
34 | (1) |
|
2.2 Writing Output but Preserving Spacing |
|
|
35 | (1) |
|
2.3 Writing Output with More Formatting Control |
|
|
36 | (2) |
|
2.4 Writing Output Without the Newline |
|
|
38 | (1) |
|
2.5 Saving Output from a Command |
|
|
39 | (1) |
|
2.6 Saving Output to Other Files |
|
|
40 | (1) |
|
2.7 Saving Output from the is Command |
|
|
41 | (1) |
|
2.8 Sending Output and Error Messages to Different Files |
|
|
42 | (1) |
|
2.9 Sending Output and Error Messages to the Same File |
|
|
43 | (2) |
|
2.10 Appending Rather than Clobbering Output |
|
|
45 | (1) |
|
2.11 Using Just the Beginning or End of a File |
|
|
46 | (1) |
|
2.12 Skipping a Header in a File |
|
|
46 | (1) |
|
2.13 Throwing Output Away |
|
|
47 | (1) |
|
2.14 Saving or Grouping Output from Several Commands |
|
|
48 | (2) |
|
2.15 Connecting Two Programs by Using Output as Input |
|
|
50 | (1) |
|
2.16 Saving a Copy of Output Even While Using It as Input |
|
|
51 | (2) |
|
2.17 Connecting Two Programs by Using Output as Arguments |
|
|
53 | (2) |
|
2.18 Using Multiple Redirects on One Line |
|
|
55 | (1) |
|
2.19 Saving Output When Redirect Doesn't Seem to Work |
|
|
56 | (2) |
|
2.20 Swapping STDERR and STDOUT |
|
|
58 | (1) |
|
2.21 Keeping Files Safe from Accidental Overwriting |
|
|
59 | (2) |
|
2.22 Clobbering a File on Purpose |
|
|
61 | (2) |
| 3 Standard Input |
|
63 | (14) |
|
3.1 Getting Input from a File |
|
|
63 | (1) |
|
3.2 Keeping Your Data with Your Script |
|
|
64 | (2) |
|
3.3 Preventing Weird Behavior in a Here-Document |
|
|
66 | (1) |
|
3.4 Indenting Here-Documents |
|
|
67 | (1) |
|
|
|
68 | (2) |
|
3.6 Getting Yes or No Input |
|
|
70 | (3) |
|
3.7 Selecting from a List of Options |
|
|
73 | (1) |
|
3.8 Prompting for a Password |
|
|
74 | (3) |
| 4 Executing Commands |
|
77 | (16) |
|
4.1 Running Any Executable |
|
|
77 | (3) |
|
4.2 Running Several Commands in Sequence |
|
|
80 | (1) |
|
4.3 Running Several Commands All at Once |
|
|
81 | (1) |
|
4.4 Telling Whether a Command Succeeded or Not |
|
|
82 | (2) |
|
4.5 Running a Command Only if Another Command Succeeded |
|
|
84 | (1) |
|
4.6 Using Fewer if Statements |
|
|
85 | (2) |
|
4.7 Running Long Jobs Unattended |
|
|
87 | (1) |
|
4.8 Displaying Error Messages When Failures Occur |
|
|
88 | (1) |
|
4.9 Running Commands from a Variable |
|
|
89 | (1) |
|
4.10 Running All Scripts in a Directory |
|
|
90 | (3) |
| 5 Basic Scripting: Shell Variables |
|
93 | (40) |
|
5.1 Documenting Your Script |
|
|
95 | (1) |
|
5.2 Embedding Documentation in Shell Scripts |
|
|
96 | (2) |
|
5.3 Promoting Script Readability |
|
|
98 | (2) |
|
5.4 Separating Variable Names from Surrounding Text |
|
|
100 | (1) |
|
|
|
101 | (2) |
|
5.6 Seeing All Variable Values |
|
|
103 | (1) |
|
5.7 Using Parameters in a Shell Script |
|
|
104 | (2) |
|
5.8 Looping Over Arguments Passed to a Script |
|
|
106 | (1) |
|
5.9 Handling Parameters with Spaces |
|
|
107 | (2) |
|
5.10 Handling Lists of Parameters with Spaces |
|
|
109 | (2) |
|
|
|
111 | (2) |
|
|
|
113 | (2) |
|
5.13 Getting Default Values |
|
|
115 | (1) |
|
5.14 Setting Default Values |
|
|
116 | (1) |
|
5.15 Using null as a Valid Default Value |
|
|
117 | (1) |
|
5.16 Using More than Just a Constant String for Default |
|
|
118 | (2) |
|
5.17 Giving an Error Message for Unset Parameters |
|
|
120 | (2) |
|
5.18 Changing Pieces of a String |
|
|
122 | (2) |
|
5.19 Getting the Absolute Value of a Number |
|
|
124 | (1) |
|
5.20 Using bash for basename |
|
|
125 | (1) |
|
5.21 Using bash for dirname |
|
|
126 | (1) |
|
5.22 Using Alternate Values for Comma Separated Values |
|
|
127 | (1) |
|
5.23 Using Array Variables |
|
|
128 | (1) |
|
5.24 Converting Between Upper-and Lowercase |
|
|
129 | (1) |
|
5.25 Converting to Camel Case |
|
|
130 | (3) |
| 6 Shell Logic and Arithmetic |
|
133 | (42) |
|
6.1 Doing Arithmetic in Your Shell Script |
|
|
133 | (3) |
|
6.2 Branching on Conditions |
|
|
136 | (4) |
|
6.3 Testing for File Characteristics |
|
|
140 | (3) |
|
6.4 Testing for More than One Thing |
|
|
143 | (1) |
|
6.5 Testing for String Characteristics |
|
|
144 | (1) |
|
|
|
145 | (2) |
|
6.7 Testing with Pattern Matches |
|
|
147 | (2) |
|
6.8 Testing with Regular Expressions |
|
|
149 | (3) |
|
6.9 Changing Behavior with Redirections |
|
|
152 | (1) |
|
|
|
153 | (2) |
|
|
|
155 | (2) |
|
6.12 Looping with a Count |
|
|
157 | (2) |
|
6.13 Looping with Floating-Point Values |
|
|
159 | (1) |
|
|
|
160 | (2) |
|
6.15 Parsing Command-Line Arguments |
|
|
162 | (3) |
|
6.16 Creating Simple Menus |
|
|
165 | (2) |
|
6.17 Changing the Prompt on Simple Menus |
|
|
167 | (1) |
|
6.18 Creating a Simple RPN Calculator |
|
|
168 | (3) |
|
6.19 Creating a Command-Line Calculator |
|
|
171 | (4) |
| 7 Intermediate Shell Tools I |
|
175 | (26) |
|
7.1 Sifting Through Files for a String |
|
|
176 | (2) |
|
7.2 Getting Just the Filename from a Search |
|
|
178 | (1) |
|
7.3 Getting a Simple True/False from a Search |
|
|
179 | (1) |
|
7.4 Searching for Text While Ignoring Case |
|
|
180 | (1) |
|
7.5 Doing a Search in a Pipeline |
|
|
181 | (1) |
|
7.6 Paring Down What the Search Finds |
|
|
182 | (2) |
|
7.7 Searching with More Complex Patterns |
|
|
184 | (1) |
|
|
|
185 | (1) |
|
7.9 Grepping Compressed Files |
|
|
186 | (1) |
|
7.10 Keeping Some Output, Discarding the Rest |
|
|
187 | (1) |
|
7.11 Keeping Only a Portion of a Line of Output |
|
|
188 | (1) |
|
7.12 Reversing the Words on Each Line |
|
|
189 | (2) |
|
7.13 Summing a List of Numbers |
|
|
191 | (1) |
|
7.14 Counting String Values with awk |
|
|
192 | (2) |
|
7.15 Counting String Values with bash |
|
|
194 | (2) |
|
7.16 Showing Data as a Quick and Easy Histogram |
|
|
196 | (2) |
|
7.17 An Easy Histogram with bash |
|
|
198 | (1) |
|
7.18 Showing a Paragraph of Text After a Found Phrase |
|
|
199 | (2) |
| 8 Intermediate Shell Tools II |
|
201 | (22) |
|
|
|
201 | (1) |
|
|
|
202 | (2) |
|
|
|
204 | (2) |
|
8.4 Cutting Out Parts of Your Output |
|
|
206 | (2) |
|
8.5 Removing Duplicate Lines |
|
|
208 | (1) |
|
|
|
209 | (2) |
|
|
|
211 | (2) |
|
8.8 Checking a tar Archive for Unique Directories |
|
|
213 | (1) |
|
8.9 Translating Characters |
|
|
214 | (1) |
|
8.10 Converting Uppercase to Lowercase |
|
|
215 | (1) |
|
8.11 Converting DOS Files to Linux Format |
|
|
216 | (1) |
|
8.12 Removing Smart Quotes |
|
|
217 | (1) |
|
8.13 Counting Lines, Words, or Characters in a File |
|
|
218 | (1) |
|
8.14 Rewrapping Paragraphs |
|
|
219 | (1) |
|
8.15 Doing More with less |
|
|
220 | (3) |
| 9 Finding Files: find, locate, slocate |
|
223 | (16) |
|
9.1 Finding All Your MP3 Files |
|
|
224 | (1) |
|
9.2 Handling Filenames Containing Odd Characters |
|
|
225 | (2) |
|
9.3 Speeding Up Operations on Found Files |
|
|
227 | (1) |
|
9.4 Finding Files Across Symbolic Links |
|
|
227 | (1) |
|
9.5 Finding Files Irrespective of Case |
|
|
228 | (1) |
|
9.6 Finding Files by Date |
|
|
229 | (1) |
|
9.7 Finding Files by Type |
|
|
230 | (1) |
|
9.8 Finding Files by Size |
|
|
231 | (1) |
|
9.9 Finding Files by Content |
|
|
232 | (1) |
|
9.10 Finding Existing Files and Content Fast |
|
|
233 | (1) |
|
9.11 Finding a File Using a List of Possible Locations |
|
|
234 | (5) |
| 10 Additional Features for Scripting |
|
239 | (24) |
|
10.1 "Daemon-izing" Your Script |
|
|
239 | (1) |
|
10.2 Reusing Code with Includes and Sourcing |
|
|
240 | (2) |
|
10.3 Using Configuration Files in a Script |
|
|
242 | (1) |
|
|
|
243 | (2) |
|
10.5 Using Functions: Parameters and Return Values |
|
|
245 | (3) |
|
|
|
248 | (4) |
|
10.7 Redefining Commands with alias |
|
|
252 | (2) |
|
10.8 Avoiding Aliases and Functions |
|
|
254 | (2) |
|
10.9 Counting Elapsed Time |
|
|
256 | (1) |
|
|
|
257 | (6) |
| 11 Working with Dates and Times |
|
263 | (18) |
|
11.1 Formatting Dates for Display |
|
|
264 | (1) |
|
11.2 Supplying a Default Date |
|
|
265 | (2) |
|
11.3 Automating Date Ranges |
|
|
267 | (3) |
|
11.4 Converting Dates and Times to Epoch Seconds |
|
|
270 | (1) |
|
11.5 Converting Epoch Seconds to Dates and Times |
|
|
271 | (1) |
|
11.6 Getting Yesterday or Tomorrow with Perl |
|
|
272 | (1) |
|
11.7 Figuring Out Date and Time Arithmetic |
|
|
273 | (2) |
|
11.8 Handling Time Zones, Daylight Saving Time, and Leap Years |
|
|
275 | (1) |
|
11.9 Using date and cron to Run a Script on the Nth Day |
|
|
276 | (2) |
|
|
|
278 | (3) |
| 12 End-User Tasks as Shell Scripts |
|
281 | (22) |
|
12.1 Starting Simple by Printing Dashes |
|
|
281 | (3) |
|
12.2 Viewing Photos in an Album |
|
|
284 | (6) |
|
12.3 Loading Your MP3 Player |
|
|
290 | (5) |
|
|
|
295 | (3) |
|
12.5 Comparing Two Documents |
|
|
298 | (5) |
| 13 Parsing and Similar Tasks |
|
303 | (38) |
|
13.1 Parsing Arguments for Your Shell Script |
|
|
303 | (4) |
|
13.2 Parsing Arguments with Your Own Error Messages |
|
|
307 | (2) |
|
|
|
309 | (1) |
|
13.4 Parsing Output into an Array |
|
|
310 | (2) |
|
13.5 Parsing Output with a Function Call |
|
|
312 | (2) |
|
13.6 Parsing Text with a read Statement |
|
|
314 | (1) |
|
13.7 Parsing with read into an Array |
|
|
315 | (1) |
|
13.8 Reading an Entire File |
|
|
315 | (2) |
|
13.9 Getting Your Plurals Right |
|
|
317 | (2) |
|
13.10 Taking It One Character at a Time |
|
|
319 | (1) |
|
13.11 Cleaning Up an SVN Source Tree |
|
|
320 | (1) |
|
13.12 Setting Up a Database with MySQL |
|
|
321 | (2) |
|
13.13 Isolating Specific Fields in Data |
|
|
323 | (3) |
|
13.14 Updating Specific Fields in Datafiles |
|
|
326 | (1) |
|
13.15 Trimming Whitespace |
|
|
327 | (4) |
|
13.16 Compressing Whitespace |
|
|
331 | (2) |
|
13.17 Processing Fixed-Length Records |
|
|
333 | (2) |
|
13.18 Processing Files with No Line Breaks |
|
|
335 | (2) |
|
13.19 Converting a Datafile to CSV |
|
|
337 | (1) |
|
13.20 Parsing a CSV Datafile |
|
|
338 | (3) |
| 14 Writing Secure Shell Scripts |
|
341 | (46) |
|
14.1 Avoiding Common Security Problems |
|
|
343 | (1) |
|
14.2 Avoiding Interpreter Spoofing |
|
|
344 | (1) |
|
14.3 Setting a Secure $PATH |
|
|
345 | (2) |
|
14.4 Clearing All Aliases |
|
|
347 | (1) |
|
14.5 Clearing the Command Hash |
|
|
348 | (1) |
|
14.6 Preventing Core Dumps |
|
|
349 | (1) |
|
14.7 Setting a Secure $IFS |
|
|
350 | (1) |
|
14.8 Setting a Secure umask |
|
|
350 | (2) |
|
14.9 Finding World-Writable Directories in Your $PATH |
|
|
352 | (2) |
|
14.10 Adding the Current Directory to the $PATH |
|
|
354 | (1) |
|
14.11 Using Secure Temporary Files |
|
|
355 | (5) |
|
|
|
360 | (2) |
|
14.13 Setting Permissions |
|
|
362 | (2) |
|
14.14 Leaking Passwords into the Process List |
|
|
364 | (1) |
|
14.15 Writing setuid or setgid Scripts |
|
|
365 | (1) |
|
14.16 Restricting Guest Users |
|
|
366 | (2) |
|
|
|
368 | (2) |
|
14.18 Running as a Non-root User |
|
|
370 | (1) |
|
14.19 Using sudo More Securely |
|
|
371 | (1) |
|
14.20 Using Passwords in Scripts |
|
|
372 | (2) |
|
14.21 Using SSH Without a Password |
|
|
374 | (9) |
|
14.22 Restricting SSH Commands |
|
|
383 | (3) |
|
14.23 Disconnecting Inactive Sessions |
|
|
386 | (1) |
| 15 Advanced Scripting |
|
387 | (42) |
|
15.1 Finding bash Portably for #! |
|
|
388 | (2) |
|
15.2 Setting a POSIX $PATH |
|
|
390 | (1) |
|
15.3 Developing Portable Shell Scripts |
|
|
391 | (2) |
|
15.4 Testing Scripts Using Virtual Machines |
|
|
393 | (3) |
|
15.5 Using for Loops Portably |
|
|
396 | (1) |
|
|
|
397 | (3) |
|
15.7 Splitting Output Only When Necessary |
|
|
400 | (2) |
|
15.8 Viewing Output in Hex |
|
|
402 | (1) |
|
15.9 Using bash Net-Redirection |
|
|
403 | (2) |
|
15.10 Finding My IP Address |
|
|
405 | (5) |
|
15.11 Getting Input from Another Machine |
|
|
410 | (1) |
|
15.12 Redirecting Output for the Life of a Script |
|
|
411 | (1) |
|
15.13 Working Around "Argument list too long" Errors |
|
|
412 | (2) |
|
15.14 Logging to syslog from Your Script |
|
|
414 | (1) |
|
15.15 Using logger Correctly |
|
|
415 | (1) |
|
15.16 Sending Email from Your Script |
|
|
416 | (5) |
|
15.17 Automating a Process Using Phases |
|
|
421 | (3) |
|
15.18 Doing Two Things at Once |
|
|
424 | (2) |
|
15.19 Running an SSH command on multiple hosts |
|
|
426 | (3) |
| 16 Configuring and Customizing bash |
|
429 | (70) |
|
16.1 bash Startup Options |
|
|
430 | (1) |
|
16.2 Customizing Your Prompt |
|
|
430 | (9) |
|
16.3 A Prompt Before Your Program Runs |
|
|
439 | (2) |
|
16.4 Changing Your $PATH Permanently |
|
|
441 | (1) |
|
16.5 Changing Your $PATH Temporarily |
|
|
442 | (5) |
|
16.6 Setting Your $CDPATH |
|
|
447 | (2) |
|
16.7 When Programs Are Not Found |
|
|
449 | (1) |
|
16.8 Shortening or Changing Command Names |
|
|
450 | (2) |
|
16.9 Adjusting Shell Behavior and Environment |
|
|
452 | (1) |
|
16.10 Adjusting readline Behavior Using .inputrc |
|
|
453 | (2) |
|
16.11 Keeping a Private Stash of Utilities by Adding~/bin |
|
|
455 | (1) |
|
16.12 Using Secondary Prompts: $PS2, $PS3, $PS4 |
|
|
456 | (2) |
|
16.13 Synchronizing Shell History Between Sessions |
|
|
458 | (1) |
|
16.14 Setting Shell History Options |
|
|
459 | (2) |
|
16.15 Creating a Better cd Command |
|
|
461 | (2) |
|
16.16 Creating and Changing Into a New Directory in One Step |
|
|
463 | (2) |
|
16.17 Getting to the Bottom of Things |
|
|
465 | (1) |
|
16.18 Adding New Features to bash Using Loadable Builtins |
|
|
466 | (5) |
|
16.19 Improving Programmable Completion |
|
|
471 | (6) |
|
16.20 Using Initialization Files Correctly |
|
|
477 | (3) |
|
16.21 Creating Self-Contained, Portable rc Files |
|
|
480 | (3) |
|
16.22 Getting Started with a Custom Configuration |
|
|
483 | (16) |
| 17 Housekeeping and Administrative Tasks |
|
499 | (52) |
|
|
|
499 | (2) |
|
17.2 Using GNU Texinfo and info on Linux |
|
|
501 | (1) |
|
17.3 Unzipping Many ZIP Files |
|
|
502 | (1) |
|
17.4 Recovering Disconnected Sessions Using screen |
|
|
503 | (3) |
|
17.5 Sharing a Single bash Session |
|
|
506 | (1) |
|
17.6 Logging an Entire Session or Batch Job |
|
|
507 | (1) |
|
17.7 Clearing the Screen When You Log Out |
|
|
508 | (2) |
|
17.8 Capturing File Metadata for Recovery |
|
|
510 | (1) |
|
17.9 Creating an Index of Many Files |
|
|
511 | (1) |
|
17.10 Using diff and patch |
|
|
512 | (4) |
|
17.11 Counting Differences in Files |
|
|
516 | (2) |
|
17.12 Removing or Renaming Files Named with Special Characters |
|
|
518 | (1) |
|
17.13 Prepending Data to a File |
|
|
519 | (3) |
|
17.14 Editing a File in Place |
|
|
522 | (2) |
|
17.15 Using sudo on a Group of Commands |
|
|
524 | (2) |
|
17.16 Finding Lines That Appear in One File but Not in Another |
|
|
526 | (3) |
|
17.17 Keeping the Most Recent N Objects |
|
|
529 | (4) |
|
17.18 Writing to a Circular Log |
|
|
533 | (2) |
|
|
|
535 | (3) |
|
17.20 Grepping ps Output Without Also Getting the grep Process Itself |
|
|
538 | (1) |
|
17.21 Finding Out Whether a Process Is Running |
|
|
539 | (2) |
|
17.22 Adding a Prefix or Suffix to Output |
|
|
541 | (1) |
|
|
|
542 | (3) |
|
|
|
545 | (2) |
|
17.25 Emulating the DOS Pause Command |
|
|
547 | (1) |
|
|
|
548 | (3) |
| 18 Working Faster by Typing Less |
|
551 | (12) |
|
18.1 Moving Quickly Among Arbitrary Directories |
|
|
552 | (2) |
|
18.2 Repeating the Last Command |
|
|
554 | (1) |
|
18.3 Running Almost the Same Command |
|
|
555 | (1) |
|
|
|
556 | (1) |
|
|
|
557 | (1) |
|
18.6 Finishing Names for You |
|
|
558 | (1) |
|
|
|
559 | (2) |
|
18.8 Big Changes, More Lines |
|
|
561 | (2) |
| 19 Tips and Traps: Common Goofs for Novices |
|
563 | (110) |
|
|
|
585 | (36) |
|
B Examples Included with bash |
|
|
621 | (10) |
|
C Command-Line Processing |
|
|
631 | (6) |
|
|
|
637 | (30) |
|
E Building bash from Source |
|
|
667 | (6) |
| Index |
|
673 | |