diff --git a/LDP/guide/docbook/abs-guide/Change.log b/LDP/guide/docbook/abs-guide/Change.log index 49e4752e..547c568a 100644 --- a/LDP/guide/docbook/abs-guide/Change.log +++ b/LDP/guide/docbook/abs-guide/Change.log @@ -6,6 +6,124 @@ http://personal.riverusers.com/~thegrendel/Change.log ------------------------------------------------------------------------ +Intermediate release. +Working toward version 4.0, Winterberry release. + +1) "System and Administrative Commands" chapter: + Added "gnome-mount" entry. + Modified "command" entry to eliminate ambiguity. + At "uname" entry, reordered usage example. + At "watch" entry, noted that piping output of "watch command" to + "grep" doesn't work. + In "Filesystem" subsection, + At "lockfile" entry, additional comment in in-line example script. + In "Job Control" subsection, + Added "killall" entry. + At "nice" entry, elaborated on "renice," "snice," and "skill." + +2) In "Communications Commands" section of "External Commands" chapter: + At "ping" entry, added in-line example script. + +3) In "Text Processing" section of "External Commands" Chapter: + At "tsort" entry, added material. + +4) In "Arrays" chapter: + Noted an exception to 'array2=( "${array1[@]}" )' array copying method. + (Thank you, Jochen, DeSmet.) + Extended "empty-array.sh" + (Thank you, Omair Eshkenazi.) + +5) In "Tests" chapter: + In "Test Constructs" section: + Fixed comment typos in "broken-links.sh" example. + (Thank you, Omair Eshkenazi.) + Added material to note about "test" builtin and /usr/bin/test + not being equivalent. + In "Other Comparison Operators" section: + Rewrote the (short) intro. + In "Test Your Knowledge of Tests" section: + Updated intro to example snippet. + +6) In "$RANDOM" section of "Variables Revisited" chapter: + Fixed typo in comment in Jipe's in-line example. + Added comment to "random-between.sh" example. + (Thank you, Omair Eshkenazi, for both of the above.) + +7) In the "Security Issues Section" of the "Miscellany" chapter: + Fixed typo in second paragraph. + (Thank you, Omair Eshkenazi.) + +8) In "List Constructs" chapter: + Modified "and list" setting variable to default value in-line example. + (Thank you, Omair Eshkenazi.) + +9) In "Job Control Commands" section of + "Internal Commands and Builtins" chapter: + At "kill" entry, added comment about additional file giving signal + listing. + +10) In "Time/Date Commands" section of "External Commands" chapter: + At "touch" entry, added tip about not overwriting files. + +11) In "Internal Commands and Builtins" chapter: + Added short usage examples to "true" and "false" entries. + +12) In "Bash, version 3" section of "Bash, versions 2 and 3" chapter: + Added "pipefail" option. + Also added this to table in "Options" chapter. + At {x..y} "braces expansion operator entry, + added a simple "echo" using this. + (Thank you, Damon Puncer, for the suggestion.) + +13) In "File and Archiving Commands" section of "External Commands" Chapter: + At "diff" entry, added note about "diffstat." + Moved "sum/cksum/md5sum/sha1sum" and "shred" entries + to "Encoding and Encryption" subsection. + +14) In "Contributed Scripts" appendix: + Added "ha.sh" hashing script. + (Thank you, Oliver Beckstein.) + Added comments to "fifo.sh" script. + (Thank you, Omair Eshkenazi.) + More explicit reference to Mark Moraes copyright before + his two scripts. + +15) Moved "Here Documents" chapter from "Beyond the Basics" section to + "Advanced Topics" section. + +16) Moved "I/O Redirection" chapter from "Beyond the Basics" section to + "Advanced Topics" section. + +17) In "/dev" section of "/dev and /proc" chapter: + Added material to "socket" footnote. + +18) Split off the three "Command" chapters into a different Part. + Put an alphabetical command cross-reference into the Introduction + to that Part. + >> This is a major reorganization of the document. << + +19) In "Special Characters" chapter: + Added "extended brace expansion" (Bash 3+) entry. + Added "{} -- placeholder for text after "xargs -i" . . . + +20) In "Reference Cards" appendix: + In "Miscellaneous Constructs" table: + Added "extended brace expansion" (Bash 3+) entry. + Added "{}" (text replacement) entry. + Added more hypertext links. + Cleanups. + +21) Delineated all references to "root user" with tags. + +22) Changed many of the tags in the document + to more appropriate , , and , etc. + +23) Changed certain of the tags to the more appropriate . + +24) Various minor fixups on example scripts. + + + Version 3.9 Spiceberry release, 05/15/06 @@ -114,7 +232,7 @@ Blaeberry release, 02/26/06 Fixed minor typo at "${parameter:+alt_value}" example. (Thank you, Jemshad O K) -8) Partitioned "Security Section" of the "Miscellany" chapter +8) Partitioned "Security Issues Section" of the "Miscellany" chapter into two subsections. Added subsection about "shc" utility for compiling script source. @@ -2289,7 +2407,7 @@ Version 1.4 (minor update) Added "Passwords" exercise ("Intermediate" section). Added "Fog Index" exercise ("Difficult" section). -13) In the "Security Section" of the "Miscellany" chapter: +13) In the "Security Issues Section" of the "Miscellany" chapter: Added 'Unix Scripting Malware' reference to the footnote. 14) In "Starting off with a Sha-Bang" chapter, diff --git a/LDP/guide/docbook/abs-guide/Moraes-COPYRIGHT b/LDP/guide/docbook/abs-guide/Moraes-COPYRIGHT index 9e2a23d9..f8a7932b 100644 --- a/LDP/guide/docbook/abs-guide/Moraes-COPYRIGHT +++ b/LDP/guide/docbook/abs-guide/Moraes-COPYRIGHT @@ -1,5 +1,7 @@ The following is the mandatory copyright notice for the two included -"contrib" scripts by Mark Moraes, "behead.sh" and "ftpget.sh". +"contrib" scripts by Mark Moraes, "behead.sh" and "ftpget.sh". It is part +of the combined HTML/source tarball of the _ABS Guide_, and included by +reference in the PDF version. /* diff --git a/LDP/guide/docbook/abs-guide/abs-guide.sgml b/LDP/guide/docbook/abs-guide/abs-guide.sgml index da531679..6e6a8c07 100644 --- a/LDP/guide/docbook/abs-guide/abs-guide.sgml +++ b/LDP/guide/docbook/abs-guide/abs-guide.sgml @@ -325,6 +325,7 @@ Uncomment line below to generate index. + @@ -351,19 +352,12 @@ Uncomment line below to generate index. - 3.9 - 15 May 2006 + 4.0 + 18 June 2006 - - 3.7 - 23 Oct 2005 - mc - 'WHORTLEBERRY' release: Bugfix Update. - - 3.8 26 Feb 2006 @@ -378,6 +372,13 @@ Uncomment line below to generate index. 'SPICEBERRY' release: Minor Update. + + 4.0 + 18 May 2006 + mc + 'WINTERBERRY' release: Major Update. + + @@ -397,8 +398,11 @@ Uncomment line below to generate index. This book is suitable for classroom use as a general introduction to programming concepts. + + + + url="http://personal.riverusers.com/~thegrendel/abs-guide-4.0.tar.bz2"> The latest update of this document, as an archived, bzip2-ed tarball including both the SGML source and rendered HTML, may @@ -467,7 +471,7 @@ Uncomment line below to generate index. linkend="builtinref">builtins, features internal to the shell. - to learn. The syntax is simple and straightforward, similar to + to learn. The syntax is simple and straightforward, similar to that of invoking and chaining together utilities at the command line, and there are only a few rules to learn. Most short scripts work right the first time, and debugging even @@ -477,18 +481,20 @@ Uncomment line below to generate index. prototyping a complex application. Getting even a limited subset of the functionality to work in a shell script is often a useful first stage in project development. This way, the structure of - the application can be tested and played with, and the major - pitfalls found before proceeding to the final coding in C, C++, - Java, or Perl. + the application can be tested and played with, + and the major pitfalls found before proceeding + to the final coding in C, + C++, Java, or Perl. Shell scripting hearkens back to the classic UNIX philosophy of breaking complex projects into simpler subtasks, of chaining together components and utilities. Many consider this a better, or at least more esthetically pleasing approach to problem solving than using one of the new generation of high powered all-in-one - languages, such as Perl, which attempt to be all things to all - people, but at the cost of forcing you to alter your thinking - processes to fit the tool. + languages, such as Perl, which attempt to + be all things to all people, but at the cost of forcing you to + alter your thinking processes to fit the tool. When not to use shell scripts @@ -498,8 +504,9 @@ Uncomment line below to generate index. a factor (sorting, hashing, etc.) Procedures involving heavy-duty math operations, - especially floating point arithmetic, arbitrary precision - calculations, or complex numbers (use C++ or FORTRAN + especially floating point arithmetic, arbitrary + precision calculations, or complex numbers (use + C++ or FORTRAN instead) Cross-platform portability required (use C or Java instead) @@ -541,29 +548,32 @@ Uncomment line below to generate index. If any of the above applies, consider a more powerful scripting - language -- perhaps Perl, Tcl, Python, Ruby -- or possibly a - high-level compiled language such as C, C++, or Java. Even then, - prototyping the application as a shell script might still be a - useful development step. + language -- perhaps Perl, + Tcl, Python, + Ruby -- or possibly a high-level + compiled language such as C, + C++, or Java. Even + then, prototyping the application as a shell script might still + be a useful development step. We will be using Bash, an acronym for Bourne-Again shell and a pun on Stephen Bourne's - now classic Bourne shell. Bash has become a de - facto standard for shell scripting on all flavors of - UNIX. Most of the principles this book covers apply equally - well to scripting with other shells, such as the Korn Shell, - from which Bash derives some of its features, + now classic Bourne shell. Bash has become + a de facto standard for shell + scripting on all flavors of UNIX. Most of the principles this + book covers apply equally well to scripting with other shells, + such as the Korn Shell, from which Bash + derives some of its features, - Many of the features of ksh88, - and even a few from the updated ksh93 + Many of the features of ksh88, + and even a few from the updated ksh93 have been merged into Bash. - and the C Shell and its variants. (Note that C Shell programming - is not recommended due to certain inherent problems, as pointed out - in an October, 1993 C Shell and its variants. (Note that + C Shell programming is not recommended due to + certain inherent problems, as pointed out in an October, 1993 Usenet - post by Tom Christiansen.) - + post by Tom Christiansen.) What follows is a tutorial on shell scripting. It relies heavily on examples to illustrate various features of the shell. @@ -663,16 +673,16 @@ Uncomment line below to generate index. magic number - magic number, a special marker that + magic number, a special marker that designates a file type, or in this case an executable shell script (type man magic for more details on this fascinating topic). Immediately following - the sha-bang is a path + the sha-bang is a path name. This is the path to the program that interprets the commands in the script, whether it be a shell, a programming language, or a utility. This command interpreter then executes the commands in the script, starting at the top (line following - the sha-bang line), ignoring comments. + the sha-bang line), ignoring comments. The #! line in a shell script @@ -827,7 +837,7 @@ fi Either: chmod 555 scriptname (gives everyone read/execute permission) - A script needs read, as + A script needs read, as well as execute permission for it to run, since the shell needs to be able to read it. @@ -849,7 +859,7 @@ fi Why not simply invoke the script with scriptname? If the directory you are in ($PWD) is where - scriptname is located, why doesn't + scriptname is located, why doesn't this work? This fails because, for security reasons, the current directory is not by default included in a user's $PATH. It is therefore necessary to @@ -860,12 +870,13 @@ fi script calls the correct command interpreter to run it. As a final step, after testing and debugging, - you would likely want to move it to /usr/local/bin (as root, of - course), to make the script available to yourself and all - other users as a system-wide executable. The script could - then be invoked by simply typing scriptname - [ENTER] from the command line. + you would likely want to move it to /usr/local/bin (as + root, of course), to make the script + available to yourself and all other users as a system-wide + executable. The script could then be invoked by simply typing + scriptname [ENTER] from the + command line. @@ -1106,9 +1117,9 @@ esac - When considering directory names, a single - dot represents the current working directory, - and two dots denote the parent + When considering directory names, a single + dot represents the current working directory, + and two dots denote the parent directory. @@ -1126,7 +1137,7 @@ esac - The dot often appears as the + The dot often appears as the destination (directory) of a file movement command. @@ -1408,9 +1419,9 @@ fi also appears in indirect variable references. - In yet another context, from the command - line, the ! invokes the - Bash history mechanism (see In yet another context, from the command + line, the ! invokes the + Bash history mechanism (see ). Note that within a script, the history mechanism is disabled. @@ -1577,7 +1588,7 @@ echo $var2 # 23skidoo A $ prefixing a variable name - indicates the value the variable + indicates the value the variable holds. @@ -1696,11 +1707,11 @@ echo $var2 # 23skidoo process ID variable The $$ variable - holds the process ID + holds the process ID A PID, or process ID, is a number assigned - to a running process. The PIDs + to a running process. The PIDs of running processes may be viewed with a ps command. @@ -1712,9 +1723,10 @@ echo $var2 # 23skidoo - () + () - command group + + command group (a=hello; echo $a) @@ -1767,8 +1779,8 @@ cp file22.{txt,backup} A command may act upon a comma-separated list of file specs within braces. - The shell does the brace - expansion. The command itself acts upon the + The shell does the brace + expansion. The command itself acts upon the result of the expansion. Filename expansion (globbing) @@ -1788,7 +1800,44 @@ cp file22.{txt,backup} - {} + + {a..z} + + + special character + {} + + + extended brace expansion + + {a..z} + + + + Extended Brace expansion + +echo {a..z} # a b c d e f g h i j k l m n o p q r s t u v w x y z +# Echoes characters between a and z. + +echo {0..3} # 0 1 2 3 +# Echoes characters between 0 and 3. + + + + The {a..z} + extended brace + expansion construction is a feature introduced + in version 3 of + Bash. + + + + + + + + + {} {} @@ -1801,7 +1850,6 @@ cp file22.{txt,backup} - Block of code [curly brackets] Also referred to as an inline group, this construct, in effect, creates an anonymous @@ -1859,6 +1907,26 @@ echo "First line is $firstline; second line is $secondline" # Will not work. + + {} + + + placeholder for text + Used after xargs + (replace + strings option). The {} double + curly brackets are a placeholder for output text. + + + ls . | xargs -i -t cp ./{} $1 +# ^^ ^^ + +# From "ex42.sh" (copydir.sh) example. + + + + + {} \; @@ -1879,7 +1947,8 @@ echo "First line is $firstline; second line is $secondline" # Will not work. - [ ] + + [ ] [] @@ -1893,12 +1962,12 @@ echo "First line is $firstline; second line is $secondline" # Will not work. test - Test expression between [ - ]. Note that [ is part of - the shell builtin test (and a synonym - for it), not a link to the external - command /usr/bin/test. + Test expression between + [ ]. Note that [ + is part of the shell builtin test (and a synonym for it), + not a link to the external command + /usr/bin/test. @@ -1916,8 +1985,8 @@ echo "First line is $firstline; second line is $secondline" # Will not work. test - Test expression between [[ ]] (shell - keyword). + Test expression between [[ ]]. This is a shell + keyword. See the discussion on the [[ ... ]] construct. @@ -2229,7 +2298,7 @@ exit 0 The stdout of each process in a pipe must be read as the stdin of the next. If this is not the case, the data stream - will block, and the pipe will not + will block, and the pipe will not behave as expected. cat file1 file2 | ls -l | sort # The output from "cat file1 file2" disappears. @@ -2245,8 +2314,8 @@ echo "variable = $variable" # variable = initial_value If one of the commands in the pipe aborts, this prematurely terminates execution of the - pipe. Called a broken pipe, this - condition sends a SIGPIPE broken pipe, this + condition sends a SIGPIPE signal. @@ -2633,7 +2702,7 @@ echo $a # 28 This corresponds to the $HOME internal variable. - ~bozo is bozo's home directory, + ~bozo is bozo's home directory, and ls ~bozo lists the contents of it. ~/ is the current user's home directory, and ls ~/ lists the contents of it. @@ -2800,7 +2869,7 @@ echo; echo Ctl-K Vertical tab. When typing text on the console or in an - xterm window, + xterm window, Ctl-K erases from the character under the cursor to end of line. Within a script, Ctl-K may behave differently, @@ -2927,7 +2996,7 @@ echo <Ctl-V><Ctl-J> A linefeed (newline) is also a whitespace character. This explains why - a blank line, consisting only + a blank line, consisting only of a linefeed, is considered whitespace. In some contexts, such as variable @@ -2961,7 +3030,7 @@ echo <Ctl-V><Ctl-J> Variables are how programming and scripting languages represent data. A variable is nothing - more than a label, a name assigned to a + more than a label, a name assigned to a location or set of locations in computer memory holding an item of data. @@ -2972,9 +3041,9 @@ echo <Ctl-V><Ctl-J> Variable Substitution - The name of a variable is a placeholder for - its value, the data it holds. Referencing its - value is called variable substitution. + The name of a variable is a placeholder for + its value, the data it holds. Referencing its + value is called variable substitution. @@ -2991,11 +3060,11 @@ echo <Ctl-V><Ctl-J> Let us carefully distinguish between the - name of a variable - and its value. If + name of a variable + and its value. If variable1 is the name of a variable, then $variable1 - is a reference to its value, + is a reference to its value, the data item it contains. @@ -3012,15 +3081,15 @@ echo <Ctl-V><Ctl-J> The only time a variable appears naked -- without the $ prefix -- is when - declared or assigned, when unset, + declared or assigned, when unset, when exported, or in the special case of a variable representing a signal (see ). Assignment may be with an - = (as in var1=27), + = (as in var1=27), in a read statement, - and at the head of a loop (for var2 in 1 2 - 3). + and at the head of a loop (for var2 in 1 2 + 3). Enclosing a referenced value in @@ -3258,7 +3327,8 @@ arch=$(uname -m) The process calling the script sets the $0 parameter. By convention, this - parameter is the name of the script. See the manpage for + parameter is the name of the script. See the manpage for execv. @@ -3436,7 +3506,7 @@ fi In everyday speech or writing, when we quote a phrase, we set it apart and give it special meaning. In a Bash script, when we quote a - string, we set it apart and protect its literal + string, we set it apart and protect its literal meaning. Certain programs and utilities reinterpret or expand @@ -3454,7 +3524,7 @@ fi works under the Bash shell. Unless there is a file named first in the current working directory. Yet - another reason to quote. (Thank you, Harald + another reason to quote. (Thank you, Harald Koenig, for pointing this out. @@ -3974,7 +4044,7 @@ bar' # Escape character \ taken literally because of strong quoting. exit command may be used to terminate a script, just as in a - C program. It can also return a value, + C program. It can also return a value, which is available to the script's parent process. @@ -4174,8 +4244,8 @@ true With version 2.02, Bash introduced the [[ ... ]] extended - test command, which performs comparisons + linkend="dblbrackets">[[ ... ]] extended + test command, which performs comparisons in a manner more familiar to programmers from other languages. Note that [[ is a keyword, not a command. @@ -4283,13 +4353,13 @@ fi - When if and then + When if and then are on same line in a condition test, a semicolon must - terminate the if statement. Both - if and then are keywords. Keywords (or commands) - begin statements, and before a new statement on the same line - begins, the old one must terminate. + terminate the if statement. Both + if and then + are keywords. Keywords (or + commands) begin statements, and before a new statement on the + same line begins, the old one must terminate. if [ -x "$filename" ]; then @@ -4353,12 +4423,13 @@ fi therefore be strictly necessary, however newer versions of Bash require it. + The test command is a Bash builtin which tests file types and compares strings. Therefore, in a Bash script, test does not call the external /usr/bin/test binary, - which is part of the sh-utils + which is part of the sh-utils package. Likewise, [ does not call /usr/bin/[, which is linked to /usr/bin/test. @@ -4376,7 +4447,13 @@ fi bash$ type ']' bash: type: ]: not found - + + + If, for some reason, you wish to use + /usr/bin/test in a Bash script, + then specify it by full pathname. + + @@ -4411,8 +4488,8 @@ fi The [[ ]] construct is the more versatile Bash version of [ ]. This - is the extended test command, adopted from - ksh88. + is the extended test command, adopted from + ksh88. No filename expansion or word splitting takes place between [[ and ]], but there is @@ -4604,29 +4681,30 @@ home=/home/bozo -u + set-user-id (suid) flag set on file - A binary owned by root + A binary owned by root with set-user-id flag set - runs with root privileges, even + runs with root privileges, even when an ordinary user invokes it. - Be aware that suid + Be aware that suid binaries may open security holes. The - suid flag has no effect on + suid flag has no effect on shell scripts. This is useful for executables (such as pppd and cdrecord) that need to access system hardware. Lacking the - suid flag, these binaries could not - be invoked by a non-root user. + suid flag, these binaries could not + be invoked by a non-root user. -rwsr-xr-t 1 root 178236 Oct 2 2000 /usr/sbin/pppd A file with the suid flag set shows - an s in its permissions. + an s in its permissions. @@ -4637,15 +4715,15 @@ home=/home/bozo sticky bit set - Commonly known as the sticky bit, the - save-text-mode flag is a special + Commonly known as the sticky bit, + the save-text-mode flag is a special type of file permission. If a file has this flag set, that file will be kept in cache memory, for quicker access. On modern UNIX systems, the sticky bit is no longer used for files, only on directories. If set on a directory, it restricts write permission. - Setting the sticky bit adds a t + Setting the sticky bit adds a t to the permissions on the file or directory listing. @@ -4658,7 +4736,7 @@ home=/home/bozo users from inadvertently overwriting or deleting each other's files in a publicly accessible directory, such as /tmp. - (The owner of the directory or root + (The owner of the directory or root can, of course, delete or rename files there.) @@ -4714,9 +4792,10 @@ home=/home/bozo Other Comparison Operators - A binary comparison operator compares two - variables or quantities. Note the separation between integer and - string comparison. + A binary comparison operator + compares two variables or quantities. Note + that integer and string comparison use a different set of + operators. <anchor id="icomparison1">integer comparison @@ -4911,7 +4990,7 @@ home=/home/bozo - Testing whether a string is <emphasis>null</emphasis> + Testing whether a string is <firstterm>null</firstterm> &strtest; @@ -4962,7 +5041,7 @@ home=/home/bozo Nested if/then Condition Tests Condition tests using the if/then - construct may be nested. The net result is identical to using the + construct may be nested. The net result is equivalent to using the && compound comparison operator above. if [ condition1 ] @@ -4982,9 +5061,11 @@ fi Testing Your Knowledge of Tests The systemwide xinitrc file can be used - to launch the X server. This file contains quite a number of - if/then tests, as the following excerpt - shows. + to launch the X server. This file contains quite a number + of if/then tests. The following + is excerpted from an ancient version of + xinitrc (Red Hat 7.1, + or thereabouts). if [ -f $HOME/.Xclients ]; then exec $HOME/.Xclients @@ -5000,9 +5081,10 @@ else fi fi - Explain the test constructs in the above excerpt, - then examine the entire file, /etc/X11/xinit/xinitrc, - and analyze the if/then test constructs + Explain the test constructs in the + above snippet, then examine an updated version of the + file, /etc/X11/xinit/xinitrc, and + analyze the if/then test constructs there. You may need to refer ahead to the discussions of grep, sed, and regular expressions. @@ -5050,19 +5132,20 @@ category=minerals # No spaces allowed after the "=". Do not confuse the = assignment - operator with the = test - operator. + operator with the = test + operator. - # = as a test operator + # = as a test operator if [ "$string1" = "$string2" ] -# if [ "X$string1" = "X$string2" ] is safer, -# to prevent an error message should one of the variables be empty. -# (The prepended "X" characters cancel out.) then command -fi +fi + +# if [ "X$string1" = "X$string2" ] is safer, +#+ to prevent an error message should one of the variables be empty. +# (The prepended "X" characters cancel out.) @@ -5173,12 +5256,15 @@ fi exponentiation - exponentiation + exponentiation + + # Bash, version 2.02, introduced the "**" exponentiation operator. let "z=5**3" echo "z = $z" # z = 125 + @@ -5237,7 +5323,7 @@ echo "z = $z" # z = 125 plus-equal (increment variable by a constant) let "var += 5" results in - var being incremented by + var being incremented by 5. @@ -5271,7 +5357,7 @@ echo "z = $z" # z = 125 times-equal times-equal (multiply variable by a constant) - let "var *= 4" results in var + let "var *= 4" results in var being multiplied by 4. @@ -5322,9 +5408,11 @@ echo "z = $z" # z = 125 Integer variables in Bash are actually signed - long (32-bit) integers, in the range of + long (32-bit) integers, in the range of -2147483648 to 2147483647. An operation that takes a variable - outside these limits will give an erroneous result. + outside these limits will give an erroneous result. + + a=2147483646 echo "a = $a" # a = 2147483646 let "a+=1" # Increment "a". @@ -5338,15 +5426,18 @@ echo "a = $a" # a = -2147483648 Bash does not understand floating point arithmetic. It - treats numbers containing a decimal point as strings. + treats numbers containing a decimal point as strings. + + a=1.5 let "b = $a + 1.3" # Error. # t2.sh: let: b = 1.5 + 1.3: syntax error in expression (error token is ".5 + 1.3") echo "b = $b" # b=1 + - Use bc in scripts that that need floating + Use bc in scripts that that need floating point calculations or math library functions. @@ -5392,7 +5483,7 @@ echo "b = $b" # b=1 left-shift-equal left-shift-equal - let "var <<= 2" results in var + let "var <<= 2" results in var left-shifted 2 bits (multiplied by 4) @@ -5657,7 +5748,7 @@ if [[ $condition1 || $condition2 ]] # Also works. comma operator The comma operator chains together two or more arithmetic operations. All the operations are - evaluated (with possible side effects), + evaluated (with possible side effects), but only the last operation is returned. @@ -5741,7 +5832,7 @@ echo "t2 = $t2 a = $a" # t2 = 5 a = 9 path to bash - the path to the Bash + the path to the Bash binary itself bash$ echo $BASH /bin/bash @@ -6300,7 +6391,7 @@ echo "Last command argument processed = $last_cmd_arg" When given a command, the shell automatically does a hash table search on the directories listed in the - path for the executable. The path + path for the executable. The path is stored in the environmental variable, $PATH, a list of directories, separated by colons. Normally, @@ -6342,7 +6433,7 @@ echo "Last command argument processed = $last_cmd_arg" Array variable holding exit status(es) of last executed - foreground foreground pipe. Interestingly enough, this does not necessarily give the same result as the exit status of the last @@ -6425,18 +6516,18 @@ echo "Last command argument processed = $last_cmd_arg" Chet Ramey attributes the above output to the behavior of - ls. If ls - writes to a pipe whose output is not read, then SIGPIPE - kills it, and its exit - status is 141. Otherwise - its exit status is 0, + ls. If ls + writes to a pipe whose output is not + read, then SIGPIPE kills it, and its exit status is + 141. Otherwise its + exit status is 0, as expected. This likewise is the case for tr. - $PIPESTATUS is a volatile variable. It needs to be captured immediately after the pipe in question, before @@ -6457,6 +6548,13 @@ echo "Last command argument processed = $last_cmd_arg" + + The pipefail option + may be useful in cases where + $PIPESTATUS does not give the desired + information. + + @@ -6707,8 +6805,8 @@ echo "Last command argument processed = $last_cmd_arg" If the $TMOUT environmental variable is set to a non-zero value - time, then the shell prompt will time out - after time seconds. This will cause a + time, then the shell prompt will time out + after $time seconds. This will cause a logout. @@ -7024,7 +7122,7 @@ echo "$@" # 3 4 5 Flags passed to script (using set). See . - This was originally a ksh + This was originally a ksh construct adopted into Bash, and unfortunately it does not seem to work reliably in Bash scripts. One possible use for it is to have a script self-test @@ -7292,7 +7390,7 @@ echo `expr index "$stringZ" 1c` # 3 # 'c' (in #3 position) matches before '1'. This is the near equivalent of - strchr() in C. + strchr() in C. @@ -7583,7 +7681,7 @@ echo ${stringZ%%b*c} # a Converting streaming audio files to - <emphasis>ogg</emphasis> + ogg &ra2ogg; @@ -7591,7 +7689,7 @@ echo ${stringZ%%b*c} # a using substring extraction constructs. - Emulating <emphasis>getopt</emphasis> + Emulating <firstterm>getopt</firstterm> &getoptsimple; @@ -7775,12 +7873,12 @@ echo ${username-`whoami`} ${parameter-default} and ${parameter:-default} are almost equivalent. The extra : makes - a difference only when parameter + a difference only when parameter has been declared, but is null. ¶msub; - The default parameter construct + The default parameter construct finds use in providing missing command-line arguments in scripts. @@ -7797,8 +7895,8 @@ filename=${1:-$DEFAULT_FILENAME} linkend="ex73">, and . Compare this method with using an and - list to supply a default command-line + linkend="anddefault">using an and + list to supply a default command-line argument. @@ -7812,7 +7910,7 @@ filename=${1:-$DEFAULT_FILENAME} If parameter not set, set it to default. Both forms nearly equivalent. The : - makes a difference only when $parameter + makes a difference only when $parameter has been declared and is null, If $parameter is null in a @@ -7839,7 +7937,8 @@ echo ${username=`whoami`} string. Both forms nearly equivalent. The : - makes a difference only when parameter + makes a difference only when + parameter has been declared and is null, see below. echo "###### \${parameter+alt_value} ########" @@ -7879,7 +7978,7 @@ echo "a = $a" # a = xyz ${parameter:?err_msg} If parameter set, use it, else print err_msg. Both forms nearly equivalent. The : - makes a difference only when parameter + makes a difference only when parameter has been declared and is null, as above. @@ -8031,7 +8130,7 @@ echo "${filename##*.}" # data These constructs have been adopted from - ksh. + ksh. @@ -8094,7 +8193,7 @@ echo "${filename##*.}" # data ${var/#Pattern/Replacement} - If prefix of + If prefix of var matches Pattern, then substitute Replacement for @@ -8105,7 +8204,7 @@ echo "${filename##*.}" # data ${var/%Pattern/Replacement} - If suffix of + If suffix of var matches Pattern, then substitute Replacement for @@ -8124,7 +8223,7 @@ echo "${filename##*.}" # data ${!varprefix@} Matches all previously declared variables beginning - with varprefix. + with varprefix. xyz23=whatever xyz24= @@ -8164,6 +8263,8 @@ echo "a = $a" # a = xyz23 xyz24 Typing variables: <command>declare</command> or <command>typeset</command> + + The declare or typeset builtins (they are exact synonyms) @@ -8220,7 +8321,7 @@ echo "n = $n" # n = 2 -a array declare -a indices - The variable indices will be treated as + The variable indices will be treated as an array. @@ -8268,7 +8369,7 @@ echo "n = $n" # n = 2 - Using the declare builtin + Using the declare builtin restricts the scope of a variable. foo () @@ -8318,8 +8419,8 @@ bar # Prints nothing. and letter_of_alphabet=z, can a reference to a return z? This can indeed be done, and - it is called an indirect reference. It - uses the unusual eval var1=\$$var2 + it is called an indirect reference. + It uses the unusual eval var1=\$$var2 notation. @@ -8406,8 +8507,8 @@ echo $? # 1 example). Fortunately, the ${!variable} notation introduced with version 2 of Bash - (see ) makes indirect referencing more - intuitive. + (see and ) makes + indirect referencing more intuitive. @@ -8439,7 +8540,7 @@ echo $? # 1 radioactive decay. Computers can only simulate randomness, and computer-generated sequences of random numbers are therefore referred to as - pseudorandom. + pseudorandom. integer in the range 0 - 32767. It should not be used to generate an encryption @@ -8469,7 +8570,7 @@ echo $? # 1 rnumber=$(((RANDOM%30/3+1)*3)) # Note that this will not work all the time. -# It fails if $RANDOM returns 0. +# It fails if $RANDOM%30 returns 0. # Frank Wang suggests the following alternative: rnumber=$(( RANDOM%27/3*3+6 )) @@ -8504,9 +8605,9 @@ echo $? # 1 As we have seen in the last example, it is best to - reseed the RANDOM + reseed the RANDOM generator each time it is invoked. Using the same seed - for RANDOM repeats the same series + for RANDOM repeats the same series of numbers. The seed of a @@ -8612,7 +8713,7 @@ echo $? # 1 <anchor id="forloopref1">for loops - for arg in [list] + for arg in [list] for @@ -9300,6 +9401,882 @@ done + + Command Substitution + + + $ + + + special character + ` + + + + Command + substitution reassigns the output of a command + For purposes of command + substitution, a command + may be an external system command, an internal scripting + builtin, or even a script function. + or even multiple commands; it literally plugs the command + output into another context. + + In a more technically correct sense, + command substitution extracts the + stdout of a command, then assigns + it to a variable using the = + operator. + + + + The classic form of command + substitution uses backquotes + (`...`). Commands within backquotes (backticks) generate + command line text. + + script_name=`basename $0` +echo "The name of this script is $script_name." + + + + The output of commands can be used as arguments to + another command, to set a variable, and even for generating + the argument list in a <link linkend="forloopref1">for</link> + loop. + + + + + rm `cat filename` # filename contains a list of files to delete. +# +# S. C. points out that "arg list too long" error might result. +# Better is xargs rm -- < filename +# ( -- covers those cases where filename begins with a - ) + +textfile_listing=`ls *.txt` +# Variable contains names of all *.txt files in current working directory. +echo $textfile_listing + +textfile_listing2=$(ls *.txt) # The alternative form of command substitution. +echo $textfile_listing2 +# Same result. + +# A possible problem with putting a list of files into a single string +# is that a newline may creep in. +# +# A safer way to assign a list of files to a parameter is with an array. +# shopt -s nullglob # If no match, filename expands to nothing. +# textfile_listing=( *.txt ) +# +# Thanks, S.C. + + + Command substitution invokes a subshell. + + + + Command substitution may result in word splitting. + COMMAND `echo a b` # 2 args: a and b + +COMMAND "`echo a b`" # 1 arg: "a b" + +COMMAND `echo` # no arg + +COMMAND "`echo`" # one empty arg + + +# Thanks, S.C. + + + Even when there is no word splitting, command + substitution can remove trailing newlines. + + # cd "`pwd`" # This should always work. +# However... + +mkdir 'dir with trailing newline +' + +cd 'dir with trailing newline +' + +cd "`pwd`" # Error message: +# bash: cd: /tmp/file with trailing newline: No such file or directory + +cd "$PWD" # Works fine. + + + + + +old_tty_setting=$(stty -g) # Save old terminal setting. +echo "Hit a key " +stty -icanon -echo # Disable "canonical" mode for terminal. + # Also, disable *local* echo. +key=$(dd bs=1 count=1 2> /dev/null) # Using 'dd' to get a keypress. +stty "$old_tty_setting" # Restore old setting. +echo "You hit ${#key} key." # ${#variable} = number of characters in $variable +# +# Hit any key except RETURN, and the output is "You hit 1 key." +# Hit RETURN, and it's "You hit 0 key." +# The newline gets eaten in the command substitution. + +Thanks, S.C. + + + + + + Using echo to output an + unquoted variable set with command + substitution removes trailing newlines characters from + the output of the reassigned command(s). This can cause + unpleasant surprises. + + dir_listing=`ls -l` +echo $dir_listing # unquoted + +# Expecting a nicely ordered directory listing. + +# However, what you get is: +# total 3 -rw-rw-r-- 1 bozo bozo 30 May 13 17:15 1.txt -rw-rw-r-- 1 bozo +# bozo 51 May 15 20:57 t2.sh -rwxr-xr-x 1 bozo bozo 217 Mar 5 21:13 wi.sh + +# The newlines disappeared. + + +echo "$dir_listing" # quoted +# -rw-rw-r-- 1 bozo 30 May 13 17:15 1.txt +# -rw-rw-r-- 1 bozo 51 May 15 20:57 t2.sh +# -rwxr-xr-x 1 bozo 217 Mar 5 21:13 wi.sh + + + + + + Command substitution even permits setting a variable to the + contents of a file, using either redirection or the cat command. + + + variable1=`<file1` # Set "variable1" to contents of "file1". +variable2=`cat file2` # Set "variable2" to contents of "file2". + # This, however, forks a new process, + #+ so the line of code executes slower than the above version. + +# Note: +# The variables may contain embedded whitespace, +#+ or even (horrors), control characters. + + + + # Excerpts from system file, /etc/rc.d/rc.sysinit +#+ (on a Red Hat Linux installation) + + +if [ -f /fsckoptions ]; then + fsckoptions=`cat /fsckoptions` +... +fi +# +# +if [ -e "/proc/ide/${disk[$device]}/media" ] ; then + hdmedia=`cat /proc/ide/${disk[$device]}/media` +... +fi +# +# +if [ ! -n "`uname -r | grep -- "-"`" ]; then + ktag="`cat /proc/version`" +... +fi +# +# +if [ $usb = "1" ]; then + sleep 5 + mouseoutput=`cat /proc/bus/usb/devices 2>/dev/null|grep -E "^I.*Cls=03.*Prot=02"` + kbdoutput=`cat /proc/bus/usb/devices 2>/dev/null|grep -E "^I.*Cls=03.*Prot=01"` +... +fi + + + + Do not set a variable to the contents of a + long text file unless you have a very good + reason for doing so. Do not set a variable to the contents of a + binary file, even as a joke. + + + Stupid script tricks + &stupscr; + + + Notice that a buffer overrun + does not occur. This is one instance where an interpreted + language, such as Bash, provides more protection from + programmer mistakes than a compiled language. + + + + + Command substitution permits setting a variable to the + output of a loop. The + key to this is grabbing the output of an echo command within the + loop. + + + Generating a variable from a loop + &csubloop; + + + + + + Command substitution makes it possible to extend the + toolset available to Bash. It is simply a matter + of writing a program or script that outputs to + stdout (like a well-behaved UNIX + tool should) and assigning that output to a variable. + + + #include <stdio.h> + +/* "Hello, world." C program */ + +int main() +{ + printf( "Hello, world." ); + return (0); +} + bash$ gcc -o hello hello.c + + + + + #!/bin/bash +# hello.sh + +greeting=`./hello` +echo $greeting + bash$ sh hello.sh +Hello, world. + + + + + + + The $(COMMAND) form has + superseded backticks for command substitution. + + output=$(sed -n /"$1"/p $file) # From "grp.sh" example. + +# Setting a variable to the contents of a text file. +File_contents1=$(cat $file1) +File_contents2=$(<$file2) # Bash permits this also. + + The $(...) form of command substitution + treats a double backslash in a different way than + `...`. + + + bash$ echo `echo \\` + + +bash$ echo $(echo \\) +\ + + + + The $(...) form of command + substitution permits nesting. + + + In fact, nesting with backticks is also possible, + but only by escaping the inner backticks, as John + Default points out. + word_count=` wc -w \`ls -l | awk '{print $9}'\` ` + + + + + + word_count=$( wc -w $(ls -l | awk '{print $9}') ) + + + Or, for something a bit more elaborate . . . + + + Finding anagrams + &agram2; + + + + + + + Examples of command substitution in shell scripts: + + + + + + + + + + + + + + + + + + + + + + + + + + Arithmetic Expansion + + + Arithmetic expansion provides a + powerful tool for performing (integer) arithmetic + operations in scripts. Translating a string into a + numerical expression is relatively straightforward using + backticks, double + parentheses, or let. + + + <anchor id="arithexpvar1">Variations + + + Arithmetic expansion with backticks (often used in + conjunction with expr) + arithmetic expansion + + arithmetic expansion + + z=`expr $z + 3` # The 'expr' command performs the expansion. + + + + + + + Arithmetic expansion with double + parentheses + double + parentheses + and using let + let + let + + + + + The use of backticks + (backquotes) in arithmetic + expansion has been superseded by double + parentheses -- + ((...)) and + $((...)) -- and also by the very + convenient let construction. + + + z=$(($z+3)) +z=$((z+3)) # Also correct. + # Within double parentheses, + #+ parameter dereferencing + #+ is optional. + +# $((EXPRESSION)) is arithmetic expansion. # Not to be confused with + #+ command substitution. + + + +# You may also use operations within double parentheses without assignment. + + n=0 + echo "n = $n" # n = 0 + + (( n += 1 )) # Increment. +# (( $n += 1 )) is incorrect! + echo "n = $n" # n = 1 + + +let z=z+3 +let "z += 3" # Quotes permit the use of spaces in variable assignment. + # The 'let' operator actually performs arithmetic evaluation, + #+ rather than expansion. + + + Examples of arithmetic expansion in scripts: + + + + + + + + + + + + + + + + + + + + + Recess Time + + + This bizarre little intermission gives the reader a chance to + relax and maybe laugh a bit. + + +
+ + + Fellow Linux user, greetings! You are reading something which + will bring you luck and good fortune. Just e-mail a copy of + this document to 10 of your friends. Before making the copies, + send a 100-line Bash script to the first person on the list + at the bottom of this letter. Then delete their name and add + yours to the bottom of the list. + + Don't break the chain! Make the copies within 48 hours. + Wilfred P. of Brooklyn failed to send out his ten copies and + woke the next morning to find his job description changed + to "COBOL programmer." Howard L. of Newport News sent + out his ten copies and within a month had enough hardware + to build a 100-node Beowulf cluster dedicated to playing + Tuxracer. Amelia V. of Chicago laughed at this letter + and broke the chain. Shortly thereafter, a fire broke out + in her terminal and she now spends her days writing + documentation for MS Windows. + + Don't break the chain! Send out your ten copies today! + + +
+ + + Courtesy 'NIX "fortune cookies", with some + alterations and many apologies + +
+ + + + + + + Commands + + + + Mastering the commands on your Linux machine is an indispensable + prelude to writing effective shell scripts. + + This section covers the following commands: + + + + + . + (See also source) + ac + adduser + agetty + agrep + ar + arch + at + autoload + awk + (See also Using + awk for + math operations) + badblocks + banner + basename + batch + bc + bg + bind + bison + builtin + bzgrep + bzip2 + cal + caller + cat + cd + chattr + chfn + chgrp + chkconfig + chmod + chown + chroot + cksum + clear + clock + cmp + col + colrm + column + comm + command + compress + cp + cpio + cron + crypt + csplit + cu + cut + date + dc + dd + debugfs + declare + depmod + df + dialog + diff + diff3 + diffstat + dig + dirname + dirs + disown + dmesg + doexec + dos2unix + du + dump + dumpe2fs + e2fsck + echo + egrep + enable + enscript + env + eqn + eval + exec + exit + (Related topic: exit + status) + expand + export + expr + factor + false + fdformat + fdisk + fg + fgrep + file + find + finger + flex + flock + fmt + fold + free + fsck + ftp + fuser + getopt + getopts + gettext + getty + gnome-mount + grep + groff + groupmod + groups + (Related topic: the $GROUPS + variable) + gs + gzip + halt + hash + hdparm + head + help + hexdump + host + hostid + hostname + (Related topic: the $HOSTNAME + variable) + hwclock + iconv + id + (Related topic: the $UID + variable) + ifconfig + info + infocmp + init + insmod + install + ipcalc + iwconfig + jobs + join + jot + kill + killall + last + lastcomm + lastlog + ldd + less + let + lex + ln + locate + lockfile + logger + logname + logout + logrotate + look + losetup + lp + ls + lsdev + lsmod + lsof + lspci + lsusb + ltrace + lynx + m4 + mail + mailto + make + MAKEDEV + man + mcookie + md5sum + mesg + mimencode + mkbootdisk + mkdir + mke2fs + mkfifo + mknod + mkswap + mktemp + mmencode + modinfo + modprobe + more + mount + msgfmt + mv + nc + netconfig + netstat + newgrp + nice + nl + nm + nmap + nohup + nslookup + objdump + od + passwd + paste + patch + (Related topic: diff) + pathchk + pgrep + pidof + ping + pkill + popd + pr + printenv + printf + procinfo + ps + pstree + ptx + pushd + pwd + (Related topic: the $PWD + variable) + quota + rcp + rdev + rdist + read + readelf + readlink + readonly + reboot + recode + renice + reset + restore + rev + rlogin + rm + rmdir + rmmod + route + rpm + rpm2cpio + rsh + rsync + runlevel + run-parts + rx + rz + sar + scp + script + sdiff + sed + seq + service + set + setquota + setserial + setterm + sha1sum + shar + shopt + shred + shutdown + size + skill + sleep + slocate + snice + sort + source + sox + split + sq + ssh + stat + strace + strings + strip + stty + su + sudo + sum + suspend + swapoff + swapon + sx + sync + sz + tac + tail + tar + tbl + tcpdump + tee + telinit + telnet + Tex + time + times + tmpwatch + top + touch + tput + tr + traceroute + true + tset + tsort + tty + tune2fs + type + typeset + ulimit + umask + umount + uname + unarc + unarj + uncompress + unexpand + uniq + units + unrar + unset + unsq + unzip + uptime + usbmodules + useradd + userdel + usermod + users + usleep + uucp + uudecode + uuencode + uux + vacation + vdir + vmstat + vrfy + w + wait + wall + watch + wc + wget + whatis + whereis + which + who + whoami + whois + write + xargs + yacc + yes + zcat + zdiff + zdump + zegrep + zfgrep + zgrep + zip + + + + + + Internal Commands and Builtins @@ -9311,7 +10288,7 @@ done A builtin is a command contained within the Bash tool - set, literally built in. This is either + set, literally built in. This is either for performance reasons -- builtins execute faster than external commands, which usually require forking off a separate process -- or because a particular builtin needs direct access to the @@ -9327,19 +10304,19 @@ done subprocess to carry out a task, this is called forking. This new process is the child, and the process - that forked it off is the + that forked it off is the parent. While the child process is doing its work, the parent process is still executing. - Note that while a parent process - gets the process ID of the - child process, and can thus - pass arguments to it, the reverse is not - true. This - can create problems that are subtle and hard to track - down. + Note that while a parent + process gets the process + ID of the child + process, and can thus pass arguments to it, + the reverse is not true. This can create problems + that are subtle and hard to track down. A script that forks off multiple instances of itself @@ -9347,7 +10324,7 @@ done - Generally, a Bash builtin + Generally, a Bash builtin does not fork a subprocess when it executes within a script. An external system command or filter in a script usually will fork a @@ -9368,15 +10345,16 @@ echo "This line uses the \"echo\" builtin." A keyword - is a reserved word, token or + is a reserved word, token or operator. Keywords have a special meaning to the shell, and indeed are the building blocks of the shell's syntax. As examples, for, while, do, and ! are keywords. Similar to a builtin, a keyword is hard-coded into - Bash, but unlike a builtin, a keyword is - not by itself a command, but part of a larger command structure. + Bash, but unlike a builtin, a keyword is + not in itself a command, but part of a larger command + structure. An exception to this is the time command, listed in the official @@ -9460,7 +10438,7 @@ fi So, how can we embed a linefeed within an - echoed character string? + echoed character string? # Embedding a linefeed? echo "Why doesn't this string \n split on two lines?" @@ -9548,7 +10526,8 @@ echo $string1 This is the Bash builtin version of the /bin/printf or /usr/bin/printf command. See the - printf manpage (of the system command) + printf manpage (of the system command) for in-depth coverage. Older versions of Bash may not support @@ -9640,7 +10619,7 @@ echo; echo "Keypress was "\"$keypress\""." The option to read - also allows detection of the arrow keys + also allows detection of the arrow keys and certain of the other unusual keys. @@ -9701,7 +10680,7 @@ done The gendiff script, usually found in /usr/bin on many Linux distros, pipes the output of find to a - while read construct. + while read construct. find $1 \( -name "*$2" -o -name ".*$2" \) -print | while read f; do @@ -9720,7 +10699,7 @@ while read f; do <anchor id="intfilesystem1">Filesystem - cd + cd cd @@ -9839,11 +10818,11 @@ while read f; do and simultaneously changes the current working directory to that directory popped from the stack. - dirs lists the contents of the directory - stack (compare this with the $DIRSTACK variable). - A successful pushd or - popd will automatically invoke + dirs lists + the contents of the directory stack (compare this + with the $DIRSTACK + variable). A successful pushd + or popd will automatically invoke dirs. @@ -9905,7 +10884,7 @@ while read f; do eval arg1 [arg2] ... [argN] Combines the arguments in an expression or list of - expressions and evaluates them. Any + expressions and evaluates them. Any variables contained within the expression are expanded. The result translates into a command. This can be useful for code generation from the command line or within a script. @@ -9942,7 +10921,7 @@ while read f; do Using <command>eval</command> to force variable - substitution in a Perl script + substitution in a Perl script &evalex; @@ -10015,7 +10994,7 @@ while read f; do Using set with the option explicitly assigns the contents of a variable to the positional parameters. When no variable follows the - , it unsets + , it unsets the positional parameters. @@ -10039,7 +11018,7 @@ while read f; do The unset command deletes a shell variable, effectively setting it to - null. Note that this command does + null. Note that this command does not affect positional parameters. @@ -10120,7 +11099,7 @@ while read f; do
- declare + declare typeset declare @@ -10144,7 +11123,7 @@ while read f; do - readonly + readonly readonly @@ -10156,7 +11135,7 @@ while read f; do sets a variable as read-only, or, in effect, as a constant. Attempts to change the variable fail with an error message. This is the shell analog of the - C language const + C language const type qualifier.
@@ -10189,8 +11168,8 @@ while read f; do This powerful tool parses command-line arguments passed to the script. This is the Bash analog of the getopt external command and the - getopt library function familiar to - C programmers. It permits passing + getopt library function familiar to + C programmers. It permits passing and concatenating multiple options A option is an argument that acts as a @@ -10229,7 +11208,7 @@ while read f; do minus (). It is the prefixed that lets getopts recognize command-line - arguments as options. + arguments as options. In fact, getopts will not process arguments without the prefixed , and will terminate option processing at the first @@ -10312,10 +11291,10 @@ shift $(($OPTIND - 1)) executes a script. Within a script, a source file-name loads the file file-name. Sourcing a file - (dot-command) imports + (dot-command) imports code into the script, appending to the script (same effect as the #include directive in a - C program). The net result is the + C program). The net result is the same as if the sourced lines of code were physically present in the body of the script. This is useful in situations when multiple scripts use a common data file @@ -10332,16 +11311,16 @@ shift $(($OPTIND - 1)) &ex38bis; - If the sourced file is itself - an executable script, then it will run, then - return control to the script that called it. - A sourced executable script may use a + If the sourced file is itself + an executable script, then it will run, then return + control to the script that called it. A + sourced executable script may use a return for this purpose. Arguments may be (optionally) passed to the - sourced file as sourced file as positional parameters. source $filename $arg1 arg2 @@ -10349,7 +11328,7 @@ shift $(($OPTIND - 1)) It is even possible for a script to - source itself, though this does not + source itself, though this does not seem to have any practical applications. @@ -10363,7 +11342,7 @@ shift $(($OPTIND - 1)) - exit + exit exit @@ -10440,7 +11419,7 @@ shift $(($OPTIND - 1)) - shopt + shopt shopt @@ -10449,11 +11428,12 @@ shift $(($OPTIND - 1)) shopt - This command permits changing shell options on the fly (see - and ). It often - appears in the Bash startup - files, but also has its uses in scripts. Needs - version 2 or later of Bash. + This command permits changing shell + options on the fly (see + and ). It often appears in the Bash + startup files, but also has + its uses in scripts. Needs version + 2 or later of Bash. shopt -s cdspell # Allows minor misspelling of directory names with 'cd' @@ -10479,7 +11459,7 @@ pwd # /home Putting a caller command inside a function echoes to stdout information about - the caller of that function. + the caller of that function. #!/bin/bash @@ -10500,7 +11480,7 @@ function1 # Line 9 of script. caller 0 # Has no effect because it's not inside a function. A caller command can also return - caller information from a script caller information from a script sourced within another script. Like a function, this is a subroutine call. @@ -10533,6 +11513,14 @@ caller 0 # Has no effect because it's not inside a function. + + +bash$ true +bash$ echo $? +0 + + + # Endless loop while true # alias for ":" do @@ -10547,7 +11535,7 @@ done - false + false false @@ -10559,6 +11547,14 @@ done linkend="exitstatusref">exit status, but does nothing else. + + +bash$ false +bash$ echo $? +1 + + + # Testing "false" if false then @@ -10585,7 +11581,7 @@ done
- type [cmd] + type [cmd] type @@ -10599,8 +11595,8 @@ done Similar to the which external command, - type cmd gives the full path name to - cmd. Unlike which, + type cmd identifies + cmd. Unlike which, type is a Bash builtin. The useful option to type identifies keywords @@ -10614,6 +11610,10 @@ done bash$ type -a '[' [ is a shell builtin [ is /usr/bin/[ + + +bash$ type type +type is a shell builtin @@ -10621,7 +11621,7 @@ done - hash [cmds] + hash [cmds] hash @@ -10641,13 +11641,13 @@ done - Hashing is a method of + Hashing is a method of creating lookup keys for data stored in a table. The data items themselves are scrambled to create keys, using one of a number of simple mathematical algorithms. - An advantage of hashing is that it + An advantage of hashing is that it is fast. A disadvantage is that collisions -- where a single key maps to more than one data item -- are possible. @@ -10666,7 +11666,7 @@ done - bind + bind bind @@ -10677,8 +11677,8 @@ done The bind builtin displays or modifies - readline - The readline library + readline + The readline library is what Bash uses for reading input in an interactive shell. key bindings. @@ -10687,7 +11687,7 @@ done - help + help help @@ -10725,7 +11725,7 @@ done - jobs + jobs jobs @@ -10743,17 +11743,17 @@ done Lists the jobs running in the background, giving the job number. - Not as useful as ps. + Not as useful as ps. It is all too easy to confuse - jobs and - processes. Certain jobs and + processes. Certain builtins, such as kill, disown, and wait accept either a job number or a - process number as an argument. The fg, - bg and jobs + process number as an argument. The fg, + bg and jobs commands accept only a job number. @@ -10777,7 +11777,7 @@ done - disown + disown disown @@ -10792,8 +11792,8 @@ done - fg - bg + fg + bg fg @@ -10838,7 +11838,7 @@ done You may use the wait command to prevent a script from exiting before a background job finishes executing (this would create a dreaded - orphan process). + orphan process).
Waiting for a process to finish before proceeding @@ -10898,7 +11898,7 @@ wait - suspend + suspend suspend @@ -10915,7 +11915,7 @@ wait - logout + logout logout @@ -10941,8 +11941,9 @@ wait Gives statistics on the system time used in executing commands, in the following form: - 0m0.020s 0m0.020s - This capability is of very limited value, since it is uncommon to + 0m0.020s 0m0.020s + + This capability is of very limited value, since it is uncommon to profile and benchmark shell scripts. @@ -10959,32 +11960,60 @@ wait Forcibly terminate a process by sending it an - appropriate terminate signal (see ). + appropriate terminate signal + (see ). A script that kills itself &selfdestruct; + kill -l lists all the - signals. A kill - -9 is a sure kill, which will - usually terminate a process that stubbornly refuses to - die with a plain kill. Sometimes, a - kill -15 works. A zombie - process, that is, a child process that has - terminated, but that the parent - process has not (yet) killed, cannot be killed by a - logged-on user -- you can't kill something that is already - dead -- but init will generally clean - it up sooner or later. + signals (as does the + file /usr/include/asm/signal.h). + A kill -9 is a sure + kill, which will usually terminate a + process that stubbornly refuses to die with a plain + kill. Sometimes, a kill + -15 works. A zombie process, + that is, a child process that has terminated, but that + the parent process + has not (yet) killed, cannot be killed by a logged-on + user -- you can't kill something that is already dead -- + but init will generally clean it up + sooner or later. + - command + killall + + killall + + + command + kill + + The killall command + kills a running process by name, + rather than by process ID. + If there are multiple instances of a particular command running, + then doing a killall on that command will + terminate them all. + + This refers to the killall + command in /usr/bin, + not the killall script in /etc/rc.d/init.d. + + + + + command command @@ -10992,9 +12021,14 @@ wait command command - The command COMMAND directive - disables aliases and functions for the command - COMMAND. + The command directive + disables aliases and functions for the command immediately + following it. + + +bash$ command ls + + This is one of three shell directives that effect script command processing. The others are @@ -11061,7 +12095,7 @@ wait - autoload + autoload autoload @@ -11072,7 +12106,7 @@ wait This is a port to Bash of the - ksh autoloader. With + ksh autoloader. With autoload in place, a function with an autoload declaration will load from an external file at its first invocation. @@ -11171,7 +12205,8 @@ wait ls provides a tree-like listing of a directory structure. Other useful options are , sort listing by file size, - , sort by file modification time, and + , sort by file modification time, + , show escape characters, and , show file inodes (see ). @@ -11249,7 +12284,7 @@ tr a-z A-Z < filename # Same effect, but starts one less process, - rev + rev rev @@ -11261,7 +12296,7 @@ tr a-z A-Z < filename # Same effect, but starts one less process, reverses each line of a file, and outputs to stdout. This does not have the same effect as tac, as it preserves the order of - the lines, but flips each one around. + the lines, but flips each one around (mirror image). bash$ cat file1.txt This is line 1. @@ -11283,7 +12318,7 @@ tr a-z A-Z < filename # Same effect, but starts one less process, - cp + cp cp @@ -11293,8 +12328,6 @@ tr a-z A-Z < filename # Same effect, but starts one less process, - - This is the file copy command. cp file1 file2 copies file1 to file2, overwriting @@ -11304,9 +12337,10 @@ tr a-z A-Z < filename # Same effect, but starts one less process, Particularly useful are the archive flag (for copying an entire directory tree), - the update flag, - and the and - recursive flags. + the update flag (which prevents + overwriting identically-named newer files), and the + and recursive + flags. cp -u source_dir/* dest_dir # "Synchronize" dest_dir to source_dir #+ by copying over all newer and not previously existing files. @@ -11316,10 +12350,10 @@ tr a-z A-Z < filename # Same effect, but starts one less process, - mv + mv - This is the file move command. It - is equivalent to a combination of cp + This is the file move command. + It is equivalent to a combination of cp and rm. It may be used to move multiple files to a directory, or even to rename a directory. For some examples of using mv in a script, @@ -11328,7 +12362,7 @@ tr a-z A-Z < filename # Same effect, but starts one less process, When used in a non-interactive script, mv takes the - (force) option to bypass user + (force) option to bypass user input. When a directory is moved to a preexisting directory, @@ -11348,7 +12382,7 @@ tr a-z A-Z < filename # Same effect, but starts one less process, - rm + rm rm @@ -11373,7 +12407,7 @@ tr a-z A-Z < filename # Same effect, but starts one less process, One way to accomplish this is to preface the filename to be - removed with a dot-slash . + removed with a dot-slash . bash$ rm ./-badname @@ -11394,7 +12428,7 @@ tr a-z A-Z < filename # Same effect, but starts one less process, - rmdir + rmdir rmdir @@ -11405,12 +12439,12 @@ tr a-z A-Z < filename # Same effect, but starts one less process, Remove directory. The directory must be empty of all files -- including invisible - dotfiles + dotfiles - Dotfiles are files whose - names begin with a dot, such as + Dotfiles are files whose + names begin with a dot, such as ~/.Xdefaults. Such filenames do not appear in a normal ls listing (although an ls -a will show @@ -11425,7 +12459,7 @@ tr a-z A-Z < filename # Same effect, but starts one less process, - mkdir + mkdir mkdir @@ -11481,7 +12515,7 @@ chmod u+s filename - chattr + chattr chattr @@ -11491,19 +12525,21 @@ chmod u+s filename - Change file attributes. This is analogous to + Change file + attributes. This is analogous to chmod above, but with different options and a different invocation syntax, and it works only on - an ext2 filesystem. + an ext2 filesystem. One particularly interesting chattr option is . A chattr +i filename marks the file - as immutable. The file cannot be modified, linked to, - or deleted , not even by root. This - file attribute can be set or removed only by root. In a - similar fashion, the option marks the - file as append only. + as immutable. The file cannot be modified, linked to, or + deleted, not even by root. This + file attribute can be set or removed only by + root. In a similar fashion, + the option marks the file as append + only. @@ -11602,8 +12638,8 @@ chmod u+s filename - man - info + man + info man @@ -11622,8 +12658,8 @@ chmod u+s filename These commands access the manual and information pages on system commands and installed utilities. When available, the - info pages usually contain a more detailed - description than do the man pages. + info pages usually contain more detailed + descriptions than do the man pages. @@ -11752,14 +12788,15 @@ find /etc -type f -exec cat '{}' \; | tr -c '.[:digit:]' '\n' \ - Deleting a file by its <emphasis>inode</emphasis> + <title>Deleting a file by its <firstterm>inode</firstterm> number &idelete; See , , and for scripts using - find. Its manpage provides more detail + find. Its manpage provides more detail on this complex and powerful command. @@ -11796,8 +12833,9 @@ find /etc -type f -exec cat '{}' \; | tr -c '.[:digit:]' '\n' \ The default command for xargs is echo. This means that input piped to xargs may have linefeeds and - other whitespace characters stripped out. + other whitespace characters stripped out. + bash$ ls -l total 0 @@ -11819,7 +12857,6 @@ find /etc -type f -exec cat '{}' \; | tr -c '.[:digit:]' '\n' \ ./sent-mail-jul-2005: while mentioning that the Linux ext2/ext3 filesystem . . . - ls | xargs -p -l gzip &ex41; + As in find, a curly bracket pair serves as a placeholder for replacement text. @@ -11920,8 +12958,8 @@ find /etc -type f -exec cat '{}' \; | tr -c '.[:digit:]' '\n' \ expr 1 / 0 - returns the error message, expr: division by - zero + returns the error message, expr: division by + zero Illegal arithmetic operations not allowed. @@ -11978,8 +13016,8 @@ find /etc -type f -exec cat '{}' \; | tr -c '.[:digit:]' '\n' \
The above script illustrates how - expr uses the escaped - parentheses -- \( ... \) -- grouping operator + expr uses the escaped + parentheses -- \( ... \) -- grouping operator in tandem with regular expression parsing to match a substring. Here is a another example, this time from real @@ -12089,7 +13127,7 @@ OneYearAgo=$(date --date='1 year ago') - zdump + zdump zdump @@ -12120,7 +13158,10 @@ OneYearAgo=$(date --date='1 year ago') Outputs very verbose timing statistics for executing a command. - time ls -l / gives something like this: + time ls -l / gives something + like this: + + 0.00user 0.01system 0:00.05elapsed 16%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (149major+27minor)pagefaults 0swaps @@ -12163,6 +13204,23 @@ OneYearAgo=$(date --date='1 year ago') or >> newfile (for ordinary files). + + Before doing a cp -u + (copy/update), use + touch to update the time stamp of files + you don't wish overwritten. + As an example, if the directory /home/bozo/tax_audit contains the + files spreadsheet-051606.data, + spreadsheet-051706.data, and + spreadsheet-051806.data, then + doing a touch spreadsheet*.data + will protect these files from being overwritten + by files with the same names during a + cp -u /home/bozo/financial_info/spreadsheet*data + /home/bozo/tax_audit. + +
@@ -12213,7 +13271,7 @@ OneYearAgo=$(date --date='1 year ago') - batch + batch batch @@ -12238,7 +13296,7 @@ OneYearAgo=$(date --date='1 year ago') - cal + cal cal @@ -12263,12 +13321,13 @@ OneYearAgo=$(date --date='1 year ago') sleep - This is the shell equivalent of a wait loop. It pauses for a - specified number of seconds, doing nothing. It can be useful - for timing or in processes running in the background, - checking for a specific event every so often (polling), - as in . - sleep 3 # Pauses 3 seconds. + This is the shell equivalent of a wait + loop. It pauses for a specified number of + seconds, doing nothing. It can be useful for timing or + in processes running in the background, checking for + a specific event every so often (polling), as in . sleep 3 # Pauses + 3 seconds. The sleep command defaults to @@ -12284,7 +13343,7 @@ OneYearAgo=$(date --date='1 year ago') - usleep + usleep usleep @@ -12293,19 +13352,21 @@ OneYearAgo=$(date --date='1 year ago') usleep - Microsleep (the u - may be read as the Greek mu, or micro- + Microsleep (the + u may be read as the Greek + mu, or micro- prefix). This is the same as sleep, above, but sleeps in microsecond - intervals. It can be used for fine-grain timing, or for - polling an ongoing process at very frequent intervals. + intervals. It can be used for fine-grained timing, + or for polling an ongoing process at very frequent + intervals. usleep 30 # Pauses 30 microseconds. - This command is part of the Red Hat initscripts / - rc-scripts package. + This command is part of the Red Hat + initscripts / rc-scripts package. The usleep command does not provide particularly accurate timing, and is therefore @@ -12314,8 +13375,8 @@ OneYearAgo=$(date --date='1 year ago') - hwclock - clock + hwclock + clock hwclock @@ -12332,8 +13393,8 @@ OneYearAgo=$(date --date='1 year ago') The hwclock command accesses or - adjusts the machine's hardware clock. Some - options require root privileges. The + adjusts the machine's hardware clock. Some options + require root privileges. The /etc/rc.d/rc.sysinit startup file uses hwclock to set the system time from the hardware clock at bootup. @@ -12368,18 +13429,19 @@ OneYearAgo=$(date --date='1 year ago') sort - File sorter, often used as a filter in a pipe. This - command sorts a text stream or file forwards or backwards, - or according to various keys or character positions. Using - the option, it merges presorted input - files. The info page lists its many - capabilities and options. See , - , and . + File sort utility, often used as a filter in a pipe. This + command sorts a text stream + or file forwards or backwards, or according to various + keys or character positions. Using the + option, it merges presorted input files. The info + page lists its many capabilities and options. See + , , + and . - tsort + tsort tsort @@ -12388,9 +13450,17 @@ OneYearAgo=$(date --date='1 year ago') topological sort - Topological sort, reading in pairs of - whitespace-separated strings and sorting according to - input patterns. + + Topological sort, reading in + pairs of whitespace-separated strings and sorting + according to input patterns. The original purpose of + tsort was to sort a list of dependencies + for an obsolete version of the ld + linker in an ancient version of UNIX. + + The results of a tsort will usually + differ markedly from those of the standard + sort command, above. @@ -12406,8 +13476,9 @@ OneYearAgo=$(date --date='1 year ago') This filter removes duplicate lines from a sorted file. It is often seen in a pipe coupled with - sort. - cat list-1 list-2 list-3 | sort | uniq > final.list + sort. + + cat list-1 list-2 list-3 | sort | uniq > final.list # Concatenates the list files, # sorts them, # removes duplicate lines, @@ -12440,8 +13511,8 @@ OneYearAgo=$(date --date='1 year ago') The sort INPUTFILE | uniq -c | sort -nr - command string produces a frequency - of occurrence listing on the + command string produces a frequency + of occurrence listing on the INPUTFILE file (the options to sort cause a reverse numerical sort). This template finds @@ -12585,7 +13656,7 @@ done - paste + paste paste @@ -12603,14 +13674,14 @@ done Tool for merging together different files into a single, multi-column file. In combination with - cut, useful for creating system log + cut, useful for creating system log files. - join + join join @@ -12660,7 +13731,7 @@ done - head + head head @@ -12669,10 +13740,10 @@ done head - lists the beginning of a file to - stdout (the default is - 10 lines, but this can be changed). It - has a number of interesting options. + lists the beginning of a file -- the default is + 10 lines, but this can be changed -- + to stdout. The command has a number of + interesting options. Which files are scripts? @@ -12689,7 +13760,7 @@ done - tail + tail tail @@ -12698,11 +13769,11 @@ done tail - lists the end of a file to stdout - (the default is 10 lines). Commonly used - to keep track of changes to a system logfile, using the - option, which outputs lines appended - to the file. + lists the end of a file -- the default is + 10 lines -- to + stdout. Commonly used to keep track of + changes to a system logfile, using the + option, which outputs lines appended to the file. Using <command>tail</command> to monitor the system log @@ -12744,8 +13815,8 @@ done Regular Expressions. It was originally a command/filter in the venerable ed line editor: - g/re/p -- global - - regular expression - print. + g/re/p -- global - + regular expression - print. grep The (or ) - option filters out matches. + option filters out matches. grep pattern1 *.txt | grep -v pattern2 # Matches all lines in "*.txt" files containing "pattern1", @@ -12927,7 +13998,7 @@ Here is some text. -- egrep - - extended grep - is the same + -- extended grep -- is the same as grep -E. This uses a somewhat different, extended set of Regular Expressions, which can make the search a bit more @@ -12940,10 +14011,11 @@ Here is some text. - fgrep - fast grep - - is the same as grep -F. It does - a literal string search (no Regular Expressions), which - usually speeds things up a bit. + fgrep -- + fast grep -- is the same as + grep -F. It does a literal string search + (no Regular Expressions), which usually speeds things up + a bit. On some Linux distros, egrep and fgrep are symbolic links to, or aliases for @@ -12957,14 +14029,16 @@ Here is some text. &dictlookup; - agrep (approximate - grep) extends the capabilities of + + agrep (approximate + grep) extends the capabilities of grep to approximate matching. The search string may differ by a specified number of characters from the resulting matches. This utility is not part of the core Linux distribution. + To search compressed files, use zgrep, zegrep, or zfgrep. These also work on non-compressed @@ -12972,6 +14046,7 @@ Here is some text. egrep, fgrep. They are handy for searching through a mixed set of files, some compressed, some not. + To search bzipped files, use bzgrep. @@ -12980,7 +14055,7 @@ Here is some text. - look + look look @@ -12991,7 +14066,7 @@ Here is some text. The command look works like grep, but does a lookup on - a dictionary, a sorted word list. + a dictionary, a sorted word list. By default, look searches for a match in /usr/dict/words, but a different dictionary file may be specified. @@ -13048,7 +14123,7 @@ Here is some text. - wc + wc wc @@ -13057,7 +14132,10 @@ Here is some text. wc - wc gives a word count on a file or I/O stream: + + wc gives a word + count on a file or I/O stream: + bash $ wc /usr/share/doc/sed-4.1.2/README 13 70 447 README [13 lines 70 words 447 characters] @@ -13069,7 +14147,7 @@ Here is some text. wc -L gives only the length of the longest line. Using wc to count how many - .txt files are in current working directory: + .txt files are in current working directory: $ ls *.txt | wc -l # Will work as long as none of the "*.txt" files have a linefeed in their name. @@ -13159,7 +14237,7 @@ tr -d 0-9 <filename X The complement - option inverts the character set to + option inverts the character set to match. With this option, tr acts only upon those characters not matching the specified set. @@ -13243,7 +14321,7 @@ tr -d 0-9 <filename - fmt + fmt fmt @@ -13273,7 +14351,7 @@ tr -d 0-9 <filename - col + col col @@ -13292,7 +14370,7 @@ tr -d 0-9 <filename - column + column column @@ -13315,7 +14393,7 @@ tr -d 0-9 <filename - colrm + colrm colrm @@ -13340,7 +14418,7 @@ tr -d 0-9 <filename - nl + nl nl @@ -13349,7 +14427,7 @@ tr -d 0-9 <filename fmt - Line numbering filter. nl filename + Line numbering filter: nl filename lists filename to stdout, but inserts consecutive numbers at the beginning of each non-blank line. If @@ -13370,7 +14448,7 @@ tr -d 0-9 <filename - pr + pr pr @@ -13444,7 +14522,7 @@ tr -d 0-9 <filename - iconv + iconv iconv @@ -13475,7 +14553,7 @@ function write_utf8_string { - recode + recode recode @@ -13486,14 +14564,15 @@ function write_utf8_string { Consider this a fancier version of iconv, above. This very versatile utility - for converting a file to a different encoding is not part - of the standard Linux installation. + for converting a file to a different encoding scheme. + Note that recode> is not part of the + standard Linux installation. - TeX - gs + TeX + gs TeX @@ -13519,7 +14598,7 @@ function write_utf8_string { shell script encapsulating all the options and arguments passed to one of these markup languages. - Ghostscript + Ghostscript (gs) is a GPL-ed Postscript interpreter. @@ -13527,7 +14606,7 @@ function write_utf8_string { - enscript + enscript enscript @@ -13545,8 +14624,8 @@ function write_utf8_string { groff - tbl - eqn + tbl + eqn groff @@ -13573,7 +14652,7 @@ function write_utf8_string { Yet another text markup and display formatting language is groff. This is the enhanced GNU version of the venerable UNIX roff/troff display - and typesetting package. Manpages + and typesetting package. Manpages use groff. The tbl table processing utility @@ -13597,8 +14676,8 @@ function write_utf8_string { - lex - yacc + lex + yacc lex @@ -13614,10 +14693,12 @@ function write_utf8_string { bison + The lex lexical analyzer produces programs for pattern matching. This has been replaced by the nonproprietary flex on Linux systems. + The yacc utility creates a parser based on a set of specifications. This has been replaced by the nonproprietary bison @@ -13648,21 +14729,24 @@ function write_utf8_string { The standard UNIX archiving utility. + An archive, in the sense discussed here, is simply a set of related files stored in a single location. + Originally a Tape ARchiving program, it has developed into a general purpose package that can handle all manner of archiving with all types of destination devices, ranging from tape drives to regular files to even stdout (see ). GNU - tar has been patched to accept various compression - filters, such as tar czvf archive_name.tar.gz - *, which recursively archives and gzips all files in a directory - tree except dotfiles - in the current working directory ($PWD). + tar has been patched to accept + various compression filters, for example: tar + czvf archive_name.tar.gz *, which recursively + archives and gzips + all files in a directory tree except dotfiles in the current + working directory ($PWD). @@ -13696,7 +14780,7 @@ function write_utf8_string { existing archive) append - (tar files to + (tar files to existing archive) list (contents of @@ -13723,7 +14807,7 @@ function write_utf8_string { It may be difficult to recover data from a - corrupted gzipped tar + corrupted gzipped tar archive. When archiving important files, make multiple backups. @@ -13731,7 +14815,7 @@ function write_utf8_string { - shar + shar shar @@ -13741,11 +14825,11 @@ function write_utf8_string { - Shell archiving utility. The files in a shell archive - are concatenated without compression, and the - resultant archive is essentially a shell script, - complete with #!/bin/sh header, - and containing all the necessary unarchiving + Shell archiving utility. + The files in a shell archive are concatenated without + compression, and the resultant archive is essentially + a shell script, complete with #!/bin/sh + header, and containing all the necessary unarchiving commands. Shar archives still show up in Internet newsgroups, but otherwise shar has been pretty well replaced by @@ -13757,7 +14841,7 @@ function write_utf8_string { - ar + ar ar @@ -13782,7 +14866,7 @@ function write_utf8_string { - The Red Hat Package Manager, or + The Red Hat Package Manager, or rpm utility provides a wrapper for source or binary archives. It includes commands for installing and checking the integrity of packages, among @@ -13807,7 +14891,7 @@ function write_utf8_string { rpm -qa gives a - complete list of all installed rpm packages + complete list of all installed rpm packages on a given system. An rpm -qa package_name lists only the package(s) corresponding to package_name. @@ -13847,7 +14931,7 @@ function write_utf8_string { - cpio + cpio cpio @@ -13874,7 +14958,7 @@ function write_utf8_string { - rpm2cpio + rpm2cpio rpm @@ -13888,7 +14972,7 @@ function write_utf8_string { linkend="rpmref">rpm one. - Unpacking an <emphasis>rpm</emphasis> archive + Unpacking an <firstterm>rpm</firstterm> archive &derpm; @@ -13923,19 +15007,21 @@ function write_utf8_string { is useful when piping to other commands. + The zcat filter decompresses a - gzipped file to + gzipped file to stdout, as possible input to a pipe or redirection. This is, in effect, a cat command that works on compressed files (including files - processed with the older compress + processed with the older compress utility). The zcat command is equivalent to gzip -dc. On some commercial UNIX systems, zcat is a synonym for uncompress -c, - and will not work on gzipped + and will not work on gzipped files. See also . @@ -13967,8 +15053,8 @@ function write_utf8_string { - compress - uncompress + compress + uncompress compress @@ -13993,13 +15079,13 @@ function write_utf8_string { treated with compress. The znew command transforms - compressed files into - gzipped ones. + compressed files into + gzipped ones. - sq + sq sq @@ -14025,7 +15111,7 @@ function write_utf8_string { - zip + zip unzip zip @@ -14043,15 +15129,15 @@ function write_utf8_string { Cross-platform file archiving and compression utility - compatible with DOS pkzip.exe. + compatible with DOS pkzip.exe. Zipped archives seem to be a more - acceptable medium of exchange on the Internet than - tarballs. + common medium of exchange on the Internet than + tarballs. - unarc + unarc unarj unrar @@ -14077,9 +15163,9 @@ function write_utf8_string { These Linux utilities permit unpacking archives - compressed with the DOS arc.exe, - arj.exe, and - rar.exe programs. + compressed with the DOS arc.exe, + arj.exe, and + rar.exe programs. @@ -14166,8 +15252,8 @@ file $DIRECTORY/* | fgrep $KEYWORD which - which command-xxx gives the full path - to command-xxx. This is useful for finding + which commandXXX gives the full path + to commandXXX. This is useful for finding out whether a particular command or utility is installed on the system. $bash which rm @@ -14177,7 +15263,7 @@ file $DIRECTORY/* | fgrep $KEYWORD - whereis + whereis whereis @@ -14187,9 +15273,9 @@ file $DIRECTORY/* | fgrep $KEYWORD Similar to which, above, - whereis command-xxx gives the - full path to command-xxx, but also to its - manpage. + whereis commandXXX gives the + full path to commandXXX, but also to its + manpage. $bash whereis rm rm: /bin/rm /usr/share/man/man1/rm.1.bz2 @@ -14229,7 +15315,7 @@ file $DIRECTORY/* | fgrep $KEYWORD - vdir + vdir vdir @@ -14239,8 +15325,10 @@ file $DIRECTORY/* | fgrep $KEYWORD Show a detailed directory listing. The effect is similar to - ls -l. - This is one of the GNU fileutils. + ls -lb. + This is one of the GNU + fileutils. + bash$ vdir total 10 @@ -14259,8 +15347,8 @@ file $DIRECTORY/* | fgrep $KEYWORD - locate - slocate + locate + slocate locate @@ -14288,7 +15376,7 @@ file $DIRECTORY/* | fgrep $KEYWORD - readlink + readlink readlink @@ -14307,7 +15395,7 @@ file $DIRECTORY/* | fgrep $KEYWORD - strings + strings strings @@ -14322,8 +15410,8 @@ file $DIRECTORY/* | fgrep $KEYWORD file. This might be handy for a quick 'n dirty examination of a core dump or for looking at an unknown graphic image file (strings image-file | more might - show something like JFIF, - which would identify the file as a jpeg + show something like JFIF, + which would identify the file as a jpeg graphic). In a script, you would probably parse the output of strings with grep or . - An <quote>improved</quote> <emphasis>strings</emphasis> - command + An <quote>improved</quote> + <firstterm>strings</firstterm> command &wstrings; @@ -14398,6 +15486,7 @@ file $DIRECTORY/* | fgrep $KEYWORD scripts. + patch: flexible versioning utility. Given a difference file generated by diff, patch can @@ -14434,14 +15523,24 @@ gzip -cd patchXX.gz | patch -p0 - Use zdiff to compare - gzipped files. + + + Use zdiff to compare + gzipped files. + + + + + Use diffstat to create + a histogram (point-distribution graph) of output from + diff. + - diff3 + diff3 diff3 @@ -14470,7 +15569,7 @@ gzip -cd patchXX.gz | patch -p0 - sdiff + sdiff sdiff @@ -14486,7 +15585,7 @@ gzip -cd patchXX.gz | patch -p0 - cmp + cmp cmp @@ -14513,13 +15612,13 @@ gzip -cd patchXX.gz | patch -p0 Use zcmp on - gzipped files. + gzipped files. - comm + comm comm @@ -14564,7 +15663,12 @@ gzip -cd patchXX.gz | patch -p0 - + + This command is useful for comparing + dictionaries or word + lists -- sorted text files with one word per + line. + @@ -14575,7 +15679,7 @@ gzip -cd patchXX.gz | patch -p0 <anchor id="fautils1">Utilities - basename + basename basename @@ -14595,7 +15699,7 @@ gzip -cd patchXX.gz | patch -p0 - dirname + dirname dirname @@ -14622,8 +15726,8 @@ gzip -cd patchXX.gz | patch -p0 - split - csplit + split + csplit split @@ -14646,17 +15750,24 @@ gzip -cd patchXX.gz | patch -p0 e-mailing or uploading them. The csplit command splits a file - according to context, the split occuring + according to context, the split occuring where patterns are matched. +
+ + + + + <anchor id="faencencr1">Encoding and Encryption + - sum - cksum + sum + cksum md5sum - sha1sum + sha1sum sum @@ -14684,7 +15795,7 @@ gzip -cd patchXX.gz | patch -p0 These are utilities for generating checksums. A - checksum is a number mathematically + checksum is a number mathematically calculated from the contents of a file, for the purpose of checking its integrity. A script might refer to a list of checksums for security purposes, such as ensuring @@ -14775,7 +15886,8 @@ gzip -cd patchXX.gz | patch -p0 the same effect as , but does it in a more thorough and elegant manner. - This is one of the GNU fileutils. + This is one of the GNU + fileutils. Advanced forensic technology may still be able to recover the contents of a file, even after application of @@ -14784,14 +15896,10 @@ gzip -cd patchXX.gz | patch -p0 - - - <anchor id="faencencr1">Encoding and Encryption - - uuencode + uuencode uuencode @@ -14800,14 +15908,16 @@ gzip -cd patchXX.gz | patch -p0 uuencode - This utility encodes binary files into ASCII characters, making them + This utility encodes binary files (images, sound files, + compressed files, etc.) into ASCII characters, making them suitable for transmission in the body of an e-mail message or in a - newsgroup posting. + newsgroup posting. This is especially useful where MIME + (multimedia) encoding is not available. - uudecode + uudecode uudecode @@ -14816,7 +15926,8 @@ gzip -cd patchXX.gz | patch -p0 uudecode - This reverses the encoding, decoding uuencoded files back into the + This reverses the encoding, decoding + uuencoded files back into the original binaries. @@ -14832,8 +15943,8 @@ gzip -cd patchXX.gz | patch -p0 - mimencode - mmencode + mimencode + mmencode mimencode @@ -14852,8 +15963,8 @@ gzip -cd patchXX.gz | patch -p0 The mimencode and mmencode commands process multimedia-encoded e-mail attachments. Although - mail user agents (such as - pine or kmail) + mail user agents (such as + pine or kmail) normally handle this automatically, these particular utilities permit manipulating such attachments manually from the command line or in a batch by means of a shell @@ -14862,7 +15973,7 @@ gzip -cd patchXX.gz | patch -p0 - crypt + crypt crypt @@ -14912,7 +16023,7 @@ gzip -cd patchXX.gz | patch -p0 Create a temporary file Creates a temporary - directory when invoked with the + directory when invoked with the option. with a unique filename. When invoked @@ -14946,7 +16057,7 @@ echo "tempfile name = $tempfile" - make + make make @@ -14966,7 +16077,7 @@ echo "tempfile name = $tempfile" - install + install install @@ -14987,7 +16098,7 @@ echo "tempfile name = $tempfile" - dos2unix + dos2unix dos2unix @@ -15004,7 +16115,7 @@ echo "tempfile name = $tempfile" - ptx + ptx ptx @@ -15021,8 +16132,8 @@ echo "tempfile name = $tempfile" - more - less + more + less more @@ -15076,7 +16187,7 @@ echo "tempfile name = $tempfile" <anchor id="communinfo1">Information and Statistics - host + host host @@ -15096,7 +16207,7 @@ echo "tempfile name = $tempfile" - ipcalc + ipcalc ipcalc @@ -15118,7 +16229,7 @@ echo "tempfile name = $tempfile" - nslookup + nslookup nslookup @@ -15135,8 +16246,7 @@ echo "tempfile name = $tempfile" or noninteractively, i.e., from within a script. The nslookup command has allegedly - been deprecated, but it still has its - uses. + been deprecated, but it is still useful. bash$ nslookup -sil 66.97.104.180 @@ -15153,7 +16263,7 @@ echo "tempfile name = $tempfile" - dig + dig dig @@ -15172,7 +16282,7 @@ echo "tempfile name = $tempfile" Some interesting options to dig are for setting a query timeout to - N seconds, for + N seconds, for continuing to query servers until a reply is received, and for doing a reverse address lookup. @@ -15217,7 +16327,7 @@ echo "tempfile name = $tempfile" - traceroute + traceroute traceroute @@ -15263,10 +16373,6 @@ echo "tempfile name = $tempfile" is a diagnostic tool for testing network connections, and it should be used with caution. - A successful ping returns an exit status of - 0. This can be tested for in a - script. bash$ ping localhost @@ -15280,6 +16386,22 @@ echo "tempfile name = $tempfile" + A successful ping returns an exit status of + 0. This can be tested for in a + script. + + HNAME=nastyspammer.com +# HNAME=$HOST # Debug: test for localhost. +count=2 # Send only two pings. + +if [[ `ping -c $count "$HNAME"` ]] +then + echo ""$HNAME" still up and broadcasting spam your way." +else + echo ""$HNAME" seems to be down. Pity." +fi + @@ -15295,13 +16417,13 @@ echo "tempfile name = $tempfile" Perform a DNS (Domain Name System) lookup. The option permits specifying which - particular whois server to query. See + particular whois server to query. See and . - finger + finger finger @@ -15344,14 +16466,14 @@ echo "tempfile name = $tempfile" finger and its associated daemon. - A daemon is a background + A daemon is a background process not attached to a terminal session. Daemons perform designated services either at specified times or explicitly triggered by certain events. The word daemon means ghost in Greek, and there is certainly something mysterious, almost supernatural, about the way UNIX daemons - silently wander about behind the scenes, carrying + wander about behind the scenes, silently carrying out their appointed tasks. @@ -15360,7 +16482,7 @@ echo "tempfile name = $tempfile" - chfn + chfn chfn @@ -15375,7 +16497,7 @@ echo "tempfile name = $tempfile" - vrfy + vrfy vrfy @@ -15385,6 +16507,9 @@ echo "tempfile name = $tempfile" Verify an Internet e-mail address. + + This command seems to be missing from newer Linux + distros. @@ -15395,7 +16520,7 @@ echo "tempfile name = $tempfile" <anchor id="commremote1">Remote Host Access - sx + sx rx sx @@ -15414,14 +16539,14 @@ echo "tempfile name = $tempfile" The sx and rx command set serves to transfer files to and from a remote - host using the xmodem protocol. These + host using the xmodem protocol. These are generally part of a communications package, such as minicom. - sz + sz rz sz @@ -15440,9 +16565,9 @@ echo "tempfile name = $tempfile" The sz and rz command set serves to transfer files to and from a remote - host using the zmodem protocol. - Zmodem has certain advantages over - xmodem, such as faster transmission + host using the zmodem protocol. + Zmodem has certain advantages over + xmodem, such as faster transmission rate and resumption of interrupted file transfers. Like sx and rx, these are generally part of a communications package. @@ -15470,9 +16595,9 @@ echo "tempfile name = $tempfile" - uucp - uux - cu + uucp + uux + cu uucp @@ -15494,11 +16619,11 @@ echo "tempfile name = $tempfile" - uucp: UNIX to UNIX - copy. This is a - communications package for transferring files between UNIX - servers. A shell script is an effective way to handle a - uucp command sequence. + uucp: UNIX to UNIX + copy. This is a communications package for + transferring files between UNIX servers. A shell script + is an effective way to handle a uucp + command sequence. Since the advent of the Internet and e-mail, uucp seems to have faded into obscurity, @@ -15511,17 +16636,18 @@ echo "tempfile name = $tempfile" --- - uux: UNIX to UNIX execute. - Execute a command on a remote system. This - command is part of the uucp package. + uux: UNIX to UNIX + execute. Execute a command on a remote system. + This command is part of the uucp + package. --- - cu: Call Up - a remote system and connect as a simple terminal. - It is a sort of dumbed-down version of telnet. This command is part - of the uucp package. + cu: Call + Up a remote system and connect as a + simple terminal. It is a sort of dumbed-down version of + telnet. This command is + part of the uucp package. @@ -15554,7 +16680,7 @@ echo "tempfile name = $tempfile" The wget utility - non-interactively retrieves or + non-interactively retrieves or downloads files from a Web or ftp site. It works well in a script. @@ -15592,8 +16718,10 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE The lynx Web and file browser can be used inside a script (with the option) to retrieve a file from a Web or - ftp site non-interactively. - lynx -dump http://www.xyz23.com/file01.html >$SAVEFILE + ftp site non-interactively. + + + lynx -dump http://www.xyz23.com/file01.html >$SAVEFILE With the option, @@ -15607,7 +16735,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE - rlogin + rlogin rlogin @@ -15623,7 +16751,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE - rsh + rsh rsh @@ -15639,7 +16767,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE - rcp + rcp rcp @@ -15654,7 +16782,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE - rsync + rsync rsync @@ -15678,10 +16806,11 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE &fc4upd; - Using rcp, rsync, - and similar utilities with security implications in a - shell script may not be advisable. Consider, instead, - using ssh, scp, + Using rcp, rsync, and similar + utilities with security implications in a shell + script may not be advisable. Consider, instead, using + ssh, scp, or an expect script. @@ -15703,7 +16832,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE secure replacement for telnet, rlogin, rcp, and rsh uses identity authentication - and encryption. See its manpage + and encryption. See its manpage for details. @@ -15727,7 +16856,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE - scp + scp scp @@ -15772,7 +16901,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE - netconfig + netconfig netconfig @@ -15782,8 +16911,8 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE A command-line utility for configuring a network adapter - (using DHCP). This command is native to Red Hat centric Linux - distros. + (using DHCP). This command is native + to Red Hat centric Linux distros. @@ -15818,7 +16947,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE - mailto + mailto mailto @@ -15836,7 +16965,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE - vacation + vacation vacation @@ -15847,7 +16976,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE This utility automatically replies to e-mails that the intended recipient is on vacation and temporarily - unavailable. This runs on a network, in conjunction with + unavailable. It runs on a network, in conjunction with sendmail, and is not applicable to a dial-up POPmail account. @@ -15869,7 +16998,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE - tput + tput tput @@ -15884,9 +17013,9 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE certain terminal operations. tput clear is the equivalent of clear, below. tput reset is the equivalent - of reset, below. tput - sgr0 also resets the terminal, but without - clearing the screen. + of reset, + below. tput sgr0 also resets the + terminal, but without clearing the screen. bash$ tput longname @@ -15906,7 +17035,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE - infocmp + infocmp infocmp @@ -15918,7 +17047,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE This command prints out extensive information about the current terminal. It references the - terminfo database. + terminfo database. bash$ infocmp @@ -15939,7 +17068,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE - reset + reset reset @@ -15974,7 +17103,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE - script + script script @@ -16002,7 +17131,7 @@ wget -r ftp://ftp.xyz24.net/~bozo/project_files/ -O $SAVEFILE numbers - factor + factor factor @@ -16193,8 +17322,8 @@ LIMIT_STRING special category - jot - seq + jot + seq jot @@ -16326,7 +17455,7 @@ done - yes + yes yes @@ -16345,9 +17474,11 @@ done may be specified, as in yes different string, which would continually output different string to - stdout. One might well ask the purpose - of this. From the command line or in a script, the output - of yes can be redirected or piped into a + stdout. + + One might well ask the purpose of this. From the + command line or in a script, the output of + yes can be redirected or piped into a program expecting user input. In effect, this becomes a sort of poor man's version of expect. @@ -16383,7 +17514,7 @@ done - banner + banner banner @@ -16400,7 +17531,7 @@ done - printenv + printenv printenv @@ -16420,7 +17551,7 @@ done - lp + lp lp @@ -16433,7 +17564,7 @@ done commands send file(s) to the print queue, to be printed as hard copy. - The print queue is + The print queue is the group of jobs waiting in line to be printed. @@ -16450,8 +17581,9 @@ done bash$ pr -options file1.txt | lp - Formatting packages, such as groff and - Ghostscript may send their output + Formatting packages, such as groff and + Ghostscript may send their output directly to lp. bash$ groff -Tascii file.tr | lp @@ -16479,7 +17611,7 @@ done [UNIX borrows an idea from the plumbing trade.] This is a redirection operator, but with a difference. Like the - plumber's tee, it permits siponing + plumber's tee, it permits siponing off to a file the output of a command or commands within a pipe, but without affecting the result. This is useful for printing an ongoing process to a file or paper, perhaps to @@ -16495,16 +17627,17 @@ done - cat listfile* | sort | tee check.file | uniq > result.file - (The file check.file contains - the concatenated sorted listfiles, - before the duplicate lines are removed by uniq.) + cat listfile* | sort | tee check.file | uniq > result.file + + (The file check.file contains + the concatenated sorted listfiles, + before the duplicate lines are removed by uniq.) - mkfifo + mkfifo mkfifo @@ -16514,8 +17647,8 @@ done This obscure command - creates a named pipe, a temporary - first-in-first-out buffer for + creates a named pipe, a temporary + first-in-first-out buffer for transferring data between processes. For an excellent overview of this @@ -16532,7 +17665,7 @@ done - pathchk + pathchk pathchk @@ -16564,8 +17697,8 @@ done dd - This is the somewhat obscure and much feared data - duplicator command. Originally a utility + This is the somewhat obscure and much feared data + duplicator command. Originally a utility for exchanging data on magnetic tapes between UNIX minicomputers and IBM mainframes, this command still has its uses. The dd command simply @@ -16674,8 +17807,8 @@ dd if=$filename conv=ucase > $filename.uppercase od - The od, or octal - dump filter converts input (or files) to octal + The od, or octal + dump filter converts input (or files) to octal (base-8) or other bases. This is useful for viewing or processing binary data files or otherwise unreadable system device files, such as /dev/urandom, @@ -16685,7 +17818,7 @@ dd if=$filename conv=ucase > $filename.uppercase - hexdump + hexdump hexdump @@ -16702,7 +17835,7 @@ dd if=$filename conv=ucase > $filename.uppercase - objdump + objdump objdump @@ -16731,7 +17864,7 @@ dd if=$filename conv=ucase > $filename.uppercase - mcookie + mcookie magic @@ -16740,20 +17873,21 @@ dd if=$filename conv=ucase > $filename.uppercase cookie + This command generates a magic cookie, a - 128-bit (32-character) pseudorandom hexadecimal number, - normally used as an authorization signature - by the X server. This also available for use in a script as - a quick 'n dirty random number. - random000=$(mcookie) - + 128-bit (32-character) pseudorandom hexadecimal number, + normally used as an authorization signature + by the X server. This also available for use in a script + as a quick 'n dirty random number. + + random000=$(mcookie) Of course, a script could use md5 for the same purpose. - # Generate md5 checksum on the script itself. + linkend="md5sumref">md5 for the same purpose. + + # Generate md5 checksum on the script itself. random001=`md5sum $0 | awk '{print $1}'` -# Uses 'awk' to strip off the filename. - +# Uses 'awk' to strip off the filename. The mcookie command gives yet another way to generate a unique filename. @@ -16767,7 +17901,7 @@ random001=`md5sum $0 | awk '{print $1}'` - units + units units @@ -16776,9 +17910,10 @@ random001=`md5sum $0 | awk '{print $1}'` conversion - This utility converts between different units of measure. - While normally invoked in interactive mode, - units may find use in a script. + This utility converts between different units + of measure. While normally invoked in interactive + mode, units may find use in a + script. Converting meters to miles &unitconversion; @@ -16788,7 +17923,7 @@ random001=`md5sum $0 | awk '{print $1}'` - m4 + m4 m4 @@ -16799,12 +17934,12 @@ random001=`md5sum $0 | awk '{print $1}'` A hidden treasure, m4 is a powerful macro processing filter, - A macro is a + A macro is a symbolic constant that expands into a command string or a set of operations on parameters. virtually a complete language. Although originally written as a pre-processor for - RatFor, m4 + RatFor, m4 turned out to be useful as a stand-alone utility. In fact, m4 combines some of the functionality of eval, @@ -16827,7 +17962,7 @@ random001=`md5sum $0 | awk '{print $1}'` - doexec + doexec doexec @@ -16837,9 +17972,9 @@ random001=`md5sum $0 | awk '{print $1}'` The doexec command enables passing - an arbitrary list of arguments to a binary - executable. In particular, passing - argv[0] (which corresponds to binary + executable. In particular, passing + argv[0] (which corresponds to $0 in a script) lets the executable be invoked by various names, and it can then carry out different sets of actions, according to the name @@ -16891,7 +18026,7 @@ esac - sox + sox sox @@ -16902,12 +18037,12 @@ esac The sox, or - sound - exchange command plays and + sound + exchange command plays and performs transformations on sound files. In fact, the /usr/bin/play executable (now deprecated) is nothing but a shell wrapper for - sox. + sox. For example, sox soundfile.wav soundfile.au changes a WAV sound file into a @@ -16940,15 +18075,15 @@ esac The startup and shutdown scripts in /etc/rc.d illustrate the uses (and usefulness) of many of these comands. These are usually - invoked by root and used for system maintenance or emergency - filesystem repairs. Use with caution, as some of these commands - may damage your system if misused. + invoked by root and used for system + maintenance or emergency filesystem repairs. Use with caution, as + some of these commands may damage your system if misused. <anchor id="usersgroups1">Users and Groups - users + users users @@ -16963,7 +18098,7 @@ esac - groups + groups groups @@ -16985,8 +18120,8 @@ esac - chown - chgrp + chown + chgrp chown @@ -17004,7 +18139,7 @@ esac The chown command changes the ownership of a file or files. This command is a useful - method that root can use to + method that root can use to shift file ownership from one user to another. An ordinary user may not change the ownership of files, not even her own files. @@ -17021,7 +18156,7 @@ esac The chgrp command changes the group ownership of a file or files. You must be owner of the file(s) as well as a member - of the destination group (or root) + of the destination group (or root) to use this operation. chgrp --recursive dunderheads *.data # The "dunderheads" group will now own all the "*.data" files @@ -17032,7 +18167,7 @@ esac - useradd + useradd userdel useradd @@ -17067,7 +18202,7 @@ esac - usermod + usermod usermod @@ -17085,7 +18220,7 @@ esac - groupmod + groupmod groupmod @@ -17180,7 +18315,7 @@ esac - w + w w @@ -17191,14 +18326,16 @@ esac Show all logged on users and the processes belonging to them. This is an extended version of who. The output of w - may be piped to grep to find a specific user and/or process. + may be piped to grep to find + a specific user and/or process. + bash$ w | grep startx bozo tty1 - 4:22pm 6:41 4.47s 0.45s startx - logname + logname logname @@ -17219,8 +18356,9 @@ esac bash$ whoami bozo - However... + However . . . + bash$ su Password: ...... @@ -17228,6 +18366,7 @@ esac root bash# logname bozo + While logname prints the name @@ -17249,16 +18388,16 @@ esac Runs a program or script as a - substitute user. + substitute user. su rjones starts a shell as user rjones. A naked su - defaults to root. See root. See . - sudo + sudo sudo @@ -17267,9 +18406,9 @@ esac sudo - Runs a command as root (or another user). This may - be used in a script, thus permitting a regular user to - run the script. + Runs a command as root (or + another user). This may be used in a script, thus permitting + a regular user to run the script. #!/bin/bash @@ -17284,7 +18423,7 @@ sudo cp /root/secretfile /home/bozo/secret - passwd + passwd passwd @@ -17297,7 +18436,7 @@ sudo cp /root/secretfile /home/bozo/secret Sets, changes, or manages a user's password. The passwd command can be used in - a script, but should not be. + a script, but probably should not be. Setting a new password @@ -17307,14 +18446,14 @@ sudo cp /root/secretfile /home/bozo/secret The passwd command's , , and options permit locking, unlocking, and deleting a user's password. Only - root may use these options. + root may use these options. - ac + ac ac @@ -17332,7 +18471,7 @@ sudo cp /root/secretfile /home/bozo/secret - last + last last @@ -17362,7 +18501,7 @@ sudo cp /root/secretfile /home/bozo/secret - newgrp + newgrp newgrp @@ -17371,10 +18510,10 @@ sudo cp /root/secretfile /home/bozo/secret group - Change user's group ID without logging out. This permits - access to the new group's files. Since users may be - members of multiple groups simultaneously, this command - finds little use. + Change user's group ID without + logging out. This permits access to the new group's + files. Since users may be members of multiple groups + simultaneously, this command finds little use. @@ -17385,7 +18524,7 @@ sudo cp /root/secretfile /home/bozo/secret <anchor id="terminalssys1">Terminals - tty + tty tty @@ -17444,7 +18583,7 @@ sudo cp /root/secretfile /home/bozo/secret terminals and modes Normally, a terminal works in the - canonical mode. When a user hits a + canonical mode. When a user hits a key, the resulting character does not immediately go to the program actually running in this terminal. A buffer local to the terminal stores keystrokes. When the user @@ -17504,7 +18643,7 @@ sudo cp /root/secretfile /home/bozo/secret - setterm + setterm setterm @@ -17540,7 +18679,7 @@ echo normal hello - tset + tset tset @@ -17565,7 +18704,7 @@ echo normal hello - setserial + setserial setserial @@ -17576,8 +18715,8 @@ echo normal hello Set or display serial port parameters. This command must be - run by root user and is usually found in a system setup - script. + run by root and is usually found in a + system setup script. # From /etc/pcmcia/serial script: @@ -17588,8 +18727,8 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ< - getty - agetty + getty + agetty getty @@ -17628,7 +18767,7 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ< on the network to write to the terminal. - It can be very annoying to have a message + It can be quite annoying to have a message about ordering pizza suddenly appear in the middle of the text file you are editing. On a multi-user network, you might therefore wish to disable write access to your @@ -17648,7 +18787,7 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ< This is an acronym for write all, i.e., sending + linkend="writeref">write all, i.e., sending a message to all users at every terminal logged into the network. It is primarily a system administrator's tool, useful, for example, when warning everyone that the @@ -17666,7 +18805,7 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ< If write access to a particular terminal has been disabled with mesg, then wall cannot send a message to - it. + that terminal. @@ -17678,7 +18817,7 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ< <anchor id="statisticssys1">Information and Statistics - uname + uname uname @@ -17693,16 +18832,21 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ< (see ). The option shows only the OS type. - bash$ uname -a -Linux localhost.localdomain 2.2.15-2.5.0 #1 Sat Feb 5 00:13:43 EST 2000 i686 unknown + bash$ uname +Linux bash$ uname -s -Linux +Linux + + +bash$ uname -a +Linux localhost.localdomain 2.6.15-1.2054_FC5 #1 Tue Mar 14 15:48:33 EST 2006 i686 i686 i386 GNU/Linux + - arch + arch arch @@ -17723,7 +18867,7 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ< - lastcomm + lastcomm lastcomm @@ -17774,7 +18918,7 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ< - lsof + lsof lsof @@ -17806,7 +18950,7 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ< - strace + strace strace @@ -17840,7 +18984,7 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ< - ltrace + ltrace ltrace @@ -17902,7 +19046,7 @@ exit 0 - nc + nc nc @@ -17912,7 +19056,7 @@ exit 0 - The nc (netcat) + The nc (netcat) utility is a complete toolkit for connecting to and listening to TCP and UDP ports. It is useful as a diagnostic and testing tool and as a component in simple script-based HTTP @@ -17924,7 +19068,8 @@ exit 0 - Checking a remote server for <emphasis>identd</emphasis> + Checking a remote server for + <firstterm>identd</firstterm> &iscan; @@ -18061,7 +19206,7 @@ exit 0 - dmesg + dmesg dmesg @@ -18090,7 +19235,7 @@ exit 0 - stat + stat stat @@ -18150,7 +19295,7 @@ exit 0 - netstat + netstat netstat @@ -18195,8 +19340,10 @@ exit 0 Shows how long the system has been running, along with associated statistics. + bash$ uptime 10:28pm up 1:57, 3 users, load average: 0.17, 0.34, 0.27 + A load average of 1 or less indicates that the system handles processes immediately. A load @@ -18288,14 +19435,14 @@ exit 0 hex to 007f0100, the exact equivalent of what hostid returns, above. There exist only a few million other Linux machines with this - identical hostid. + identical hostid. - sar + sar sar @@ -18338,7 +19485,7 @@ Average: all 6.33 1.70 14.71 0.00 77.26 - readelf + readelf elf @@ -18348,8 +19495,8 @@ Average: all 6.33 1.70 14.71 0.00 77.26 Show information and statistics about a designated - elf binary. This is part of the - binutils package. + elf binary. This is part of the + binutils package. bash$ readelf -h /bin/bash ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 @@ -18364,7 +19511,7 @@ Average: all 6.33 1.70 14.71 0.00 77.26 - size + size size @@ -18391,7 +19538,7 @@ Average: all 6.33 1.70 14.71 0.00 77.26System Logs - logger + logger logger @@ -18403,14 +19550,18 @@ Average: all 6.33 1.70 14.71 0.00 77.26Appends a user-generated message to the system log (/var/log/messages). You do not have - to be root to invoke logger. + to be root to invoke + logger. + + logger Experiencing instability in network connection at 23:10, 05/21. # Now, do a 'tail /var/log/messages'. By embedding a logger command in a script, it is possible to write debugging information to - /var/log/messages. - logger -t $0 -i Logging at line "$LINENO". + /var/log/messages. + + logger -t $0 -i Logging at line "$LINENO". # The "-t" option specifies the tag for the logger entry. # The "-i" option records the process ID. @@ -18423,7 +19574,7 @@ Average: all 6.33 1.70 14.71 0.00 77.26 - logrotate + logrotate logrotate @@ -18492,8 +19643,8 @@ Average: all 6.33 1.70 14.71 0.00 77.26 - pgrep - pkill + pgrep + pkill pgrep @@ -18533,12 +19684,15 @@ Average: all 6.33 1.70 14.71 0.00 77.26 + Compare the action of pkill with killall. + - pstree + pstree pstree @@ -18555,7 +19709,7 @@ Average: all 6.33 1.70 14.71 0.00 77.26 - top + top top @@ -18590,7 +19744,7 @@ Average: all 6.33 1.70 14.71 0.00 77.26 - nice + nice nice @@ -18599,17 +19753,21 @@ Average: all 6.33 1.70 14.71 0.00 77.26nice + Run a background job with an altered priority. Priorities run from 19 (lowest) to -20 - (highest). Only root may set the + (highest). Only root may set the negative (higher) priorities. Related commands are - renice, snice, - and skill. + renice and snice, + which change the priority of a running process or + processes, and skill, which sends a + kill signal to a process + or processes. - nohup + nohup nohup @@ -18622,8 +19780,9 @@ Average: all 6.33 1.70 14.71 0.00 77.26&. If you use nohup within a script, consider coupling it with a wait to avoid creating an orphan - or zombie process. + linkend="waitref">wait to avoid creating an + orphan or + zombie process. @@ -18637,12 +19796,13 @@ Average: all 6.33 1.70 14.71 0.00 77.26process ID - Identifies process ID (PID) of a + Identifies process ID (PID) of a running job. Since job control commands, such as kill and renice - act on the PID of a process (not - its name), it is sometimes necessary to identify that - PID. The pidof + linkend="killref">kill and renice act on the + PID of a process (not its + name), it is sometimes necessary to identify that + PID. The pidof command is the approximate counterpart to the $PPID internal variable. @@ -18661,7 +19821,7 @@ Average: all 6.33 1.70 14.71 0.00 77.26 - fuser + fuser fuser @@ -18714,7 +19874,7 @@ Average: all 6.33 1.70 14.71 0.00 77.26 The fuser command, invoked with the option identifies the processes - accessing a port. This + accessing a port. This is especially useful in combination with nmap. @@ -18771,7 +19931,7 @@ Average: all 6.33 1.70 14.71 0.00 77.26Process Control and Booting - init + init init @@ -18786,12 +19946,13 @@ Average: all 6.33 1.70 14.71 0.00 77.26init determines the runlevel of the system from /etc/inittab. Invoked by its alias - telinit, and by root only. + telinit, and by + root only. - telinit + telinit telinit @@ -18802,13 +19963,14 @@ Average: all 6.33 1.70 14.71 0.00 77.26 Symlinked to init, this is a means of changing the system runlevel, usually done for system maintenance or emergency filesystem - repairs. Invoked only by root. This command can be dangerous - be - certain you understand it well before using! + repairs. Invoked only by root. This + command can be dangerous -- be certain you understand it + well before using! - runlevel + runlevel runlevel @@ -18827,9 +19989,9 @@ Average: all 6.33 1.70 14.71 0.00 77.26 - halt - shutdown - reboot + halt + shutdown + reboot halt @@ -18857,7 +20019,7 @@ Average: all 6.33 1.70 14.71 0.00 77.26 - service + service service @@ -18887,7 +20049,7 @@ Average: all 6.33 1.70 14.71 0.00 77.26Network - ifconfig + ifconfig ifconfig @@ -18896,7 +20058,7 @@ Average: all 6.33 1.70 14.71 0.00 77.26ifconfig - Network interface configuration + Network interface configuration and tuning utility. bash$ ifconfig -a @@ -18946,7 +20108,7 @@ echo `/sbin/ifconfig | grep ^[a-z] | awk '{print $1}'` - iwconfig + iwconfig iwconfig @@ -18987,7 +20149,7 @@ echo `/sbin/ifconfig | grep ^[a-z] | awk '{print $1}'` - chkconfig + chkconfig chkconfig @@ -19018,7 +20180,7 @@ echo `/sbin/ifconfig | grep ^[a-z] | awk '{print $1}'` - tcpdump + tcpdump tcpdump @@ -19027,19 +20189,21 @@ echo `/sbin/ifconfig | grep ^[a-z] | awk '{print $1}'` tcp - Network packet sniffer. This is a tool for + Network packet sniffer. This is a tool for analyzing and troubleshooting traffic on a network by dumping packet headers that match specified criteria. Dump ip packet traffic between hosts bozoville and - caduceus: + caduceus: + + bash$ tcpdump ip host bozoville and caduceus Of course, the output of tcpdump can be - parsed, using certain of the previously discussed text processing utilities. @@ -19138,15 +20302,51 @@ ls -alR # List the files in the directory tree there. The automount utility, if properly installed, can mount and unmount floppies or - CDROM disks as they are accessed or removed. On laptops - with swappable floppy and CDROM drives, this can cause - problems, though. + CDROM disks as they are accessed or removed. On + multispindle laptops with swappable + floppy and optical drives, this can cause problems, + however. + + + + + + + gnome-mount + + gnome-mount + + + command + mount + + + The newer Linux distros have deprecated + mount and umount. + The successor, for command-line mounting of removable storage + devices, is gnome-mount. It can take the + option to mount a device file by its listing + in /dev. + + For example, to mount a USB flash drive: + + + bash$ gnome-mount -d /dev/sda1 +gnome-mount 0.4 + + +bash$ df +. . . + /dev/sda1 63584 12034 51550 19% /media/disk + + + - sync + sync sync @@ -19200,7 +20400,7 @@ mount -o loop /dev/loop0 /mnt # Mount it. - mkswap + mkswap mkswap @@ -19216,8 +20416,8 @@ mount -o loop /dev/loop0 /mnt # Mount it. - swapon - swapoff + swapon + swapoff swapon @@ -19249,9 +20449,10 @@ mount -o loop /dev/loop0 /mnt # Mount it. mke2fs - Create a Linux ext2 filesystem. This command must - be invoked as root. - + Create a Linux ext2 + filesystem. This command must be invoked as + root. + Adding a new hard drive @@ -19265,7 +20466,7 @@ mount -o loop /dev/loop0 /mnt # Mount it. - tune2fs + tune2fs tune2fs @@ -19274,9 +20475,10 @@ mount -o loop /dev/loop0 /mnt # Mount it. tune2fs - Tune ext2 filesystem. May be used to change filesystem - parameters, such as maximum mount count. This must be - invoked as root. + Tune ext2 filesystem. May be + used to change filesystem parameters, such as maximum + mount count. This must be invoked as + root. This is an extremely dangerous command. Use it at your own risk, as you may inadvertently destroy your filesystem. @@ -19286,7 +20488,7 @@ mount -o loop /dev/loop0 /mnt # Mount it. - dumpe2fs + dumpe2fs dumpe2fs @@ -19296,7 +20498,8 @@ mount -o loop /dev/loop0 /mnt # Mount it. Dump (list to stdout) very verbose - filesystem info. This must be invoked as root. + filesystem info. This must be invoked as + root. root# dumpe2fs /dev/hda7 | grep 'ount count' dumpe2fs 1.19, 13-Jul-2000 for EXT2 FS 0.5b, 95/08/09 @@ -19307,7 +20510,7 @@ mount -o loop /dev/loop0 /mnt # Mount it. - hdparm + hdparm hdparm @@ -19317,7 +20520,8 @@ mount -o loop /dev/loop0 /mnt # Mount it. List or change hard disk parameters. This command must be - invoked as root, and it may be dangerous if misused. + invoked as root, and it may be + dangerous if misused. @@ -19333,7 +20537,7 @@ mount -o loop /dev/loop0 /mnt # Mount it. Create or change a partition table on a storage device, usually a hard drive. This command must be invoked as - root. + root. Use this command with extreme caution. If something goes wrong, you may destroy an existing filesystem. @@ -19342,8 +20546,8 @@ mount -o loop /dev/loop0 /mnt # Mount it. fsck - e2fsck - debugfs + e2fsck + debugfs fsck @@ -19380,14 +20584,15 @@ mount -o loop /dev/loop0 /mnt # Mount it. is to (attempt to) recover deleted files. For advanced users only! - All of these should be invoked as root, and they - can damage or destroy a filesystem if misused. + All of these should be invoked as + root, and they can damage or destroy + a filesystem if misused. - badblocks + badblocks badblocks @@ -19407,15 +20612,16 @@ mount -o loop /dev/loop0 /mnt # Mount it. tests a floppy disk. The badblocks command - may be invoked destructively (overwrite all data) or in - non-destructive read-only mode. If root user owns the - device to be tested, as is generally the case, then root + may be invoked destructively (overwrite all data) or + in non-destructive read-only mode. If root + user owns the device to be tested, as is + generally the case, then root must invoke this command. - lsusb + lsusb usbmodules lsusb @@ -19442,7 +20648,7 @@ mount -o loop /dev/loop0 /mnt # Mount it. devices. - root# lsusb + bash$ lsusb Bus 001 Device 001: ID 0000:0000 Device Descriptor: bLength 18 @@ -19463,7 +20669,7 @@ mount -o loop /dev/loop0 /mnt # Mount it. - lspci + lspci lspci @@ -19493,7 +20699,7 @@ mount -o loop /dev/loop0 /mnt # Mount it. - mkbootdisk + mkbootdisk mkbootdisk @@ -19511,7 +20717,7 @@ mount -o loop /dev/loop0 /mnt # Mount it. - chroot + chroot chroot @@ -19527,17 +20733,19 @@ mount -o loop /dev/loop0 /mnt # Mount it. CHange ROOT directory. Normally commands are fetched from $PATH, relative to - /, the default root - directory. This changes the root directory to a different - one (and also changes the working directory to there). - This is useful for security purposes, for instance when - the system administrator wishes to restrict certain users, - such as those telnetting - in, to a secured portion of the filesystem (this - is sometimes referred to as confining a guest user - to a chroot jail). Note that after a - chroot, the execution path for system - binaries is no longer valid. + /, the default + root + directory. This changes the + root directory to a different one + (and also changes the working directory to there). This is + useful for security purposes, for instance when the system + administrator wishes to restrict certain users, such as + those telnetting in, + to a secured portion of the filesystem (this is sometimes + referred to as confining a guest user to a chroot + jail). Note that after a chroot, + the execution path for system binaries is no longer + valid. A chroot /opt would cause references to rpm option) or running a readonly filesystem from a CD ROM. - Invoke only as root, and use with care. + Invoke only as root, and use with + care. It might be necessary to copy certain system - files to a chrooted directory, + files to a chrooted directory, since the normal $PATH can no longer be relied upon. @@ -19572,7 +20781,7 @@ mount -o loop /dev/loop0 /mnt # Mount it. - lockfile + lockfile lockfile @@ -19583,11 +20792,12 @@ mount -o loop /dev/loop0 /mnt # Mount it. This utility is part of the procmail package (www.procmail.org). - It creates a lock file, a semaphore file that - controls access to a file, device, or resource. The lock file - serves as a flag that this particular file, device, or resource is - in use by a particular process (busy), and - this permits only restricted access (or no access) to other + It creates a lock file, a + semaphore file that controls access to a file, device, + or resource. The lock file serves as a flag that this + particular file, device, or resource is in use by a + particular process (busy), and this + permits only restricted access (or no access) to other processes. lockfile /home/bozo/lockfiles/$0.lock @@ -19616,14 +20826,15 @@ mount -o loop /dev/loop0 /mnt # Mount it. # Application "xyzip" created lock file "/var/lock/xyzip.lock". if [ -e "/var/lock/$appname.lock" ] -then +then #+ Prevent other programs & scripts + # from accessing files/resources used by xyzip. ... - flock + flock flock @@ -19652,7 +20863,7 @@ then - mknod + mknod mknod @@ -19670,7 +20881,7 @@ then - MAKEDEV + MAKEDEV MAKEDEV @@ -19679,19 +20890,17 @@ then make device file - Utility for creating device files. It must be run as root, - and in the /dev - directory. - root# ./MAKEDEV + Utility for creating device files. It must be run as + root, and in the /dev directory. It is a sort + of advanced version of mknod. - This is a sort of advanced version of - mknod. - tmpwatch + tmpwatch tmpwatch @@ -19714,8 +20923,8 @@ then <anchor id="periphsys1">Backup - dump - restore + dump + restore dump @@ -19747,7 +20956,7 @@ then - fdformat + fdformat fdformat @@ -19756,7 +20965,8 @@ then floppy - Perform a low-level format on a floppy disk. + Perform a low-level format on a floppy disk + (/dev/fd0*). @@ -19767,7 +20977,7 @@ then <anchor id="sysresources1">System Resources - ulimit + ulimit ulimit @@ -19777,7 +20987,7 @@ then - Sets an upper limit on use + Sets an upper limit on use of system resources. Usually invoked with the option, which sets a limit on file size (ulimit -f 1000 limits files to 1 meg @@ -19791,8 +21001,8 @@ then Judicious use of ulimit can - protect a system against the dreaded fork - bomb. + protect a system against the dreaded fork + bomb. #!/bin/bash @@ -19812,7 +21022,7 @@ exit 0 # Will not exit here, because this script will never terminate.A ulimit -Hu XX (where XX is the user process limit) in /etc/profile would abort - this script when it exceeds the preset limit. + this script when it exceeded the preset limit. @@ -19890,7 +21100,7 @@ exit 0 # Will not exit here, because this script will never terminate. - rdev + rdev rdev @@ -19914,7 +21124,7 @@ exit 0 # Will not exit here, because this script will never terminate.Modules - lsmod + lsmod lsmod @@ -19946,7 +21156,7 @@ exit 0 # Will not exit here, because this script will never terminate. - insmod + insmod insmod @@ -19957,12 +21167,12 @@ exit 0 # Will not exit here, because this script will never terminate. Force installation of a kernel module (use modprobe instead, when possible). Must - be invoked as root. + be invoked as root. - rmmod + rmmod rmmod @@ -19972,12 +21182,12 @@ exit 0 # Will not exit here, because this script will never terminate. Force unloading of a kernel module. Must be invoked - as root. + as root. - modprobe + modprobe modprobe @@ -19987,12 +21197,13 @@ exit 0 # Will not exit here, because this script will never terminate. Module loader that is normally invoked automatically - in a startup script. Must be invoked as root. + in a startup script. Must be invoked as + root. - depmod + depmod depmod @@ -20001,13 +21212,13 @@ exit 0 # Will not exit here, because this script will never terminate.loadable modules - Creates module dependency file, usually invoked from + Creates module dependency file. Usually invoked from a startup script. - modinfo + modinfo modinfo @@ -20035,7 +21246,7 @@ exit 0 # Will not exit here, because this script will never terminate.Miscellaneous - env + env env @@ -20076,7 +21287,7 @@ print "even when I don't know where to find Perl.\n"; - ldd + ldd ldd @@ -20107,11 +21318,15 @@ print "even when I don't know where to find Perl.\n"; with the option. watch -n 5 tail /var/log/messages # Shows tail end of system log, /var/log/messages, every five seconds. + + Unfortunately, piping + the output of watch command to grep does not work. - strip + strip strip @@ -20130,7 +21345,7 @@ print "even when I don't know where to find Perl.\n"; - nm + nm nm @@ -20144,7 +21359,7 @@ print "even when I don't know where to find Perl.\n"; - rdist + rdist rdist @@ -20165,9 +21380,16 @@ print "even when I don't know where to find Perl.\n"; Analyzing a System Script + + Using our knowledge of administrative commands, let us examine a system script. One of the shortest and simplest to understand scripts is - killall, used to suspend running processes at system shutdown. + killall, + The killall system + script should not be confused with the killall command in /usr/bin. + used to suspend running processes at system shutdown. <command>killall</command>, from <filename class="directory">/etc/rc.d/init.d</filename> @@ -20183,8 +21405,9 @@ print "even when I don't know where to find Perl.\n"; than killall, but similar in concept. Make a copy of this script somewhere in your home directory and experiment with it (do not run it as - root). Do a simulated run with the flags - (sh -vn scriptname). Add extensive + root). Do a simulated run + with the flags (sh + -vn scriptname). Add extensive comments. Change the action commands to echos. @@ -20202,1236 +21425,19 @@ print "even when I don't know where to find Perl.\n"; + - - Command Substitution - - - $ - - - special character - ` - - - - Command - substitution reassigns the output of a command - For purposes of command - substitution, a command - may be an external system command, an internal - scripting builtin, or even a script function. - or even multiple commands; it literally plugs the command - output into another context. - In a more technically correct sense, - command substitution extracts the - stdout of a command, then assigns - it to a variable using the = - operator. - - - - The classic form of command - substitution uses backquotes - (`...`). Commands within backquotes (backticks) generate - command line text. - - script_name=`basename $0` -echo "The name of this script is $script_name." - - - - The output of commands can be used as arguments to - another command, to set a variable, and even for generating - the argument list in a <link linkend="forloopref1">for</link> - loop. - - - - - rm `cat filename` # filename contains a list of files to delete. -# -# S. C. points out that "arg list too long" error might result. -# Better is xargs rm -- < filename -# ( -- covers those cases where filename begins with a - ) - -textfile_listing=`ls *.txt` -# Variable contains names of all *.txt files in current working directory. -echo $textfile_listing - -textfile_listing2=$(ls *.txt) # The alternative form of command substitution. -echo $textfile_listing2 -# Same result. - -# A possible problem with putting a list of files into a single string -# is that a newline may creep in. -# -# A safer way to assign a list of files to a parameter is with an array. -# shopt -s nullglob # If no match, filename expands to nothing. -# textfile_listing=( *.txt ) -# -# Thanks, S.C. - - - Command substitution invokes a subshell. - - - - Command substitution may result in word splitting. - COMMAND `echo a b` # 2 args: a and b - -COMMAND "`echo a b`" # 1 arg: "a b" - -COMMAND `echo` # no arg - -COMMAND "`echo`" # one empty arg - - -# Thanks, S.C. - - - Even when there is no word splitting, command - substitution can remove trailing newlines. - - # cd "`pwd`" # This should always work. -# However... - -mkdir 'dir with trailing newline -' - -cd 'dir with trailing newline -' - -cd "`pwd`" # Error message: -# bash: cd: /tmp/file with trailing newline: No such file or directory - -cd "$PWD" # Works fine. - - - - - -old_tty_setting=$(stty -g) # Save old terminal setting. -echo "Hit a key " -stty -icanon -echo # Disable "canonical" mode for terminal. - # Also, disable *local* echo. -key=$(dd bs=1 count=1 2> /dev/null) # Using 'dd' to get a keypress. -stty "$old_tty_setting" # Restore old setting. -echo "You hit ${#key} key." # ${#variable} = number of characters in $variable -# -# Hit any key except RETURN, and the output is "You hit 1 key." -# Hit RETURN, and it's "You hit 0 key." -# The newline gets eaten in the command substitution. - -Thanks, S.C. - - - - - - Using echo to output an - unquoted variable set with command - substitution removes trailing newlines characters from - the output of the reassigned command(s). This can cause - unpleasant surprises. - - dir_listing=`ls -l` -echo $dir_listing # unquoted - -# Expecting a nicely ordered directory listing. - -# However, what you get is: -# total 3 -rw-rw-r-- 1 bozo bozo 30 May 13 17:15 1.txt -rw-rw-r-- 1 bozo -# bozo 51 May 15 20:57 t2.sh -rwxr-xr-x 1 bozo bozo 217 Mar 5 21:13 wi.sh - -# The newlines disappeared. - - -echo "$dir_listing" # quoted -# -rw-rw-r-- 1 bozo 30 May 13 17:15 1.txt -# -rw-rw-r-- 1 bozo 51 May 15 20:57 t2.sh -# -rwxr-xr-x 1 bozo 217 Mar 5 21:13 wi.sh - - - - - - Command substitution even permits setting a variable to the - contents of a file, using either redirection or the cat command. - - - variable1=`<file1` # Set "variable1" to contents of "file1". -variable2=`cat file2` # Set "variable2" to contents of "file2". - # This, however, forks a new process, - #+ so the line of code executes slower than the above version. - -# Note: -# The variables may contain embedded whitespace, -#+ or even (horrors), control characters. - - - - # Excerpts from system file, /etc/rc.d/rc.sysinit -#+ (on a Red Hat Linux installation) - - -if [ -f /fsckoptions ]; then - fsckoptions=`cat /fsckoptions` -... -fi -# -# -if [ -e "/proc/ide/${disk[$device]}/media" ] ; then - hdmedia=`cat /proc/ide/${disk[$device]}/media` -... -fi -# -# -if [ ! -n "`uname -r | grep -- "-"`" ]; then - ktag="`cat /proc/version`" -... -fi -# -# -if [ $usb = "1" ]; then - sleep 5 - mouseoutput=`cat /proc/bus/usb/devices 2>/dev/null|grep -E "^I.*Cls=03.*Prot=02"` - kbdoutput=`cat /proc/bus/usb/devices 2>/dev/null|grep -E "^I.*Cls=03.*Prot=01"` -... -fi - - - - Do not set a variable to the contents of a - long text file unless you have a very good - reason for doing so. Do not set a variable to the contents of a - binary file, even as a joke. - - - Stupid script tricks - &stupscr; - - - Notice that a buffer overrun - does not occur. This is one instance where an interpreted - language, such as Bash, provides more protection from - programmer mistakes than a compiled language. - - - - - Command substitution permits setting a variable to the - output of a loop. The - key to this is grabbing the output of an echo command within the - loop. - - - Generating a variable from a loop - &csubloop; - - - - - - Command substitution makes it possible to extend the - toolset available to Bash. It is simply a matter - of writing a program or script that outputs to - stdout (like a well-behaved UNIX - tool should) and assigning that output to a variable. - - - #include <stdio.h> - -/* "Hello, world." C program */ - -int main() -{ - printf( "Hello, world." ); - return (0); -} - bash$ gcc -o hello hello.c - - - - - #!/bin/bash -# hello.sh - -greeting=`./hello` -echo $greeting - bash$ sh hello.sh -Hello, world. - - - - - - - The $(COMMAND) form has - superseded backticks for command substitution. - - output=$(sed -n /"$1"/p $file) # From "grp.sh" example. - -# Setting a variable to the contents of a text file. -File_contents1=$(cat $file1) -File_contents2=$(<$file2) # Bash permits this also. - - The $(...) form of command substitution - treats a double backslash in a different way than - `...`. - - - bash$ echo `echo \\` - - -bash$ echo $(echo \\) -\ - - - - The $(...) form of command - substitution permits nesting. - - - In fact, nesting with backticks is also possible, - but only by escaping the inner backticks, as John - Default points out. - word_count=` wc -w \`ls -l | awk '{print $9}'\` ` - - - - - - word_count=$( wc -w $(ls -l | awk '{print $9}') ) - - - Or, for something a bit more elaborate . . . - - - Finding anagrams - &agram2; - - - - - - - Examples of command substitution in shell scripts: - - - - - - - - - - - - - - - - - - - - - - - - - - Arithmetic Expansion - - - Arithmetic expansion provides a - powerful tool for performing (integer) arithmetic operations - in scripts. Translating a string into a numerical - expression is relatively straightforward using - backticks, double parentheses, or let. - - - <anchor id="arithexpvar1">Variations - - - Arithmetic expansion with backticks (often used in - conjunction with expr) - arithmetic expansion - - arithmetic expansion - - z=`expr $z + 3` # The 'expr' command performs the expansion. - - - - - - - Arithmetic expansion with double parentheses - double - parentheses - and using let - let - let - - - - - The use of backticks in arithmetic - expansion has been superseded by double parentheses -- - ((...)) and - $((...)) -- and also by the very - convenient let construction. - - - z=$(($z+3)) -z=$((z+3)) # Also correct. - # Within double parentheses, - #+ parameter dereferencing - #+ is optional. - -# $((EXPRESSION)) is arithmetic expansion. # Not to be confused with - #+ command substitution. - - - -# You may also use operations within double parentheses without assignment. - - n=0 - echo "n = $n" # n = 0 - - (( n += 1 )) # Increment. -# (( $n += 1 )) is incorrect! - echo "n = $n" # n = 1 - - -let z=z+3 -let "z += 3" # Quotes permit the use of spaces in variable assignment. - # The 'let' operator actually performs arithmetic evaluation, - #+ rather than expansion. - - - Examples of arithmetic expansion in scripts: - - - - - - - - - - - - - - - - - - - - I/O Redirection - - - - There are always three default files - open, stdin (the keyboard), - stdout (the screen), and - stderr (error messages output to the - screen). These, and any other open files, can be redirected. - Redirection simply means capturing output from a file, command, - program, script, or even code block within a script (see and ) and sending it as - input to another file, command, program, or script. - - Each open file gets assigned a file descriptor. - - A file descriptor - is simply a number that the operating system assigns - to an open file to keep track of it. Consider it - a simplified version of a file pointer. It is - analogous to a file handle in - C. - - The file descriptors for stdin, - stdout, and stderr are - 0, 1, and 2, respectively. For opening additional files, there - remain descriptors 3 to 9. It is sometimes useful to assign one of - these additional file descriptors to stdin, - stdout, or stderr - as a temporary duplicate link. - Using file - descriptor 5 might cause problems. - When Bash creates a child process, as with exec, the child inherits - fd 5 (see Chet Ramey's archived e-mail, - SUBJECT: RE: File descriptor 5 is held open). - Best leave this particular fd alone. - This simplifies restoration to normal after complex redirection - and reshuffling (see ). - - - - COMMAND_OUTPUT > - # Redirect stdout to a file. - # Creates the file if not present, otherwise overwrites it. - - ls -lR > dir-tree.list - # Creates a file containing a listing of the directory tree. - - : > filename - # The > truncates file "filename" to zero length. - # If file not present, creates zero-length file (same effect as 'touch'). - # The : serves as a dummy placeholder, producing no output. - - > filename - # The > truncates file "filename" to zero length. - # If file not present, creates zero-length file (same effect as 'touch'). - # (Same result as ": >", above, but this does not work with some shells.) - - COMMAND_OUTPUT >> - # Redirect stdout to a file. - # Creates the file if not present, otherwise appends to it. - - - # Single-line redirection commands (affect only the line they are on): - # -------------------------------------------------------------------- - - 1>filename - # Redirect stdout to file "filename." - 1>>filename - # Redirect and append stdout to file "filename." - 2>filename - # Redirect stderr to file "filename." - 2>>filename - # Redirect and append stderr to file "filename." - &>filename - # Redirect both stdout and stderr to file "filename." - - M>N - # "M" is a file descriptor, which defaults to 1, if not explicitly set. - # "N" is a filename. - # File descriptor "M" is redirect to file "N." - M>&N - # "M" is a file descriptor, which defaults to 1, if not set. - # "N" is another file descriptor. - - #============================================================================== - - # Redirecting stdout, one line at a time. - LOGFILE=script.log - - echo "This statement is sent to the log file, \"$LOGFILE\"." 1>$LOGFILE - echo "This statement is appended to \"$LOGFILE\"." 1>>$LOGFILE - echo "This statement is also appended to \"$LOGFILE\"." 1>>$LOGFILE - echo "This statement is echoed to stdout, and will not appear in \"$LOGFILE\"." - # These redirection commands automatically "reset" after each line. - - - - # Redirecting stderr, one line at a time. - ERRORFILE=script.errors - - bad_command1 2>$ERRORFILE # Error message sent to $ERRORFILE. - bad_command2 2>>$ERRORFILE # Error message appended to $ERRORFILE. - bad_command3 # Error message echoed to stderr, - #+ and does not appear in $ERRORFILE. - # These redirection commands also automatically "reset" after each line. - #============================================================================== - - - - 2>&1 - # Redirects stderr to stdout. - # Error messages get sent to same place as standard output. - - i>&j - # Redirects file descriptor i to j. - # All output of file pointed to by i gets sent to file pointed to by j. - - >&j - # Redirects, by default, file descriptor 1 (stdout) to j. - # All stdout gets sent to file pointed to by j. - - 0< FILENAME - < FILENAME - # Accept input from a file. - # Companion command to >, and often used in combination with it. - # - # grep search-word <filename - - - [j]<>filename - # Open file "filename" for reading and writing, and assign file descriptor "j" to it. - # If "filename" does not exist, create it. - # If file descriptor "j" is not specified, default to fd 0, stdin. - # - # An application of this is writing at a specified place in a file. - echo 1234567890 > File # Write string to "File". - exec 3<> File # Open "File" and assign fd 3 to it. - read -n 4 <&3 # Read only 4 characters. - echo -n . >&3 # Write a decimal point there. - exec 3>&- # Close fd 3. - cat File # ==> 1234.67890 - # Random access, by golly. - - - - | - # Pipe. - # General purpose process and command chaining tool. - # Similar to >, but more general in effect. - # Useful for chaining commands, scripts, files, and programs together. - cat *.txt | sort | uniq > result-file - # Sorts the output of all the .txt files and deletes duplicate lines, - # finally saves results to result-file. - - - Multiple instances of input and output redirection - and/or pipes can be combined in a single command - line. - - command < input-file > output-file - -command1 | command2 | command3 > output-file - See and . - - - Multiple output streams may be redirected to one file. - - ls -yz >> command.log 2>&1 -# Capture result of illegal options "yz" in file "command.log." -# Because stderr is redirected to the file, -#+ any error messages will also be there. - -# Note, however, that the following does *not* give the same result. -ls -yz 2>&1 >> command.log -# Outputs an error message and does not write to file. - -# If redirecting both stdout and stderr, -#+ the order of the commands makes a difference. - - - - - <anchor id="cfd">Closing File Descriptors - - - n<&- - - Close input file descriptor - n. - - - - - 0<&- - <&- - - Close stdin. - - - - - n>&- - - Close output file descriptor n. - - - - - 1>&- - >&- - - Close stdout. - - - - - - - Child processes inherit open file descriptors. This is why pipes - work. To prevent an fd from being inherited, close it. - # Redirecting only stderr to a pipe. - -exec 3>&1 # Save current "value" of stdout. -ls -l 2>&1 >&3 3>&- | grep bad 3>&- # Close fd 3 for 'grep' (but not 'ls'). -# ^^^^ ^^^^ -exec 3>&- # Now close it for the remainder of the script. - -# Thanks, S.C. - - - For a more detailed introduction to I/O redirection see - . - - - - - Using <command>exec</command> - - - - - An exec <filename command redirects - stdin to a file. From that point on, all - stdin comes from that file, rather than - its normal source (usually keyboard input). This provides a - method of reading a file line by line and possibly parsing - each line of input using sed - and/or awk. - - - Redirecting <filename>stdin</filename> using - <command>exec</command> - &redir1; - - - Similarly, an exec >filename - command redirects stdout to a designated - file. This sends all command output that would normally go - to stdout to that file. - - - - exec N > filename affects the entire - script or current shell. Redirection in - the PID of the script or shell - from that point on has changed. However . . . - - - N > filename affects only the newly-forked process, - not the entire script or shell. - - Thank you, Ahmed Darwish, for pointing this out. - - - - - - Redirecting <filename>stdout</filename> using - <command>exec</command> - &reassignstdout; - - - - Redirecting both <filename>stdin</filename> and - <filename>stdout</filename> in the same script with - <command>exec</command> - &upperconv; - - - I/O redirection is a clever way of avoiding the dreaded inaccessible variables within a subshell - problem. - - - Avoiding a subshell - &avoidsubshell; - - - - - - - - - Redirecting Code Blocks - - Blocks of code, such as while, until, and for loops, even if/then test blocks can also incorporate - redirection of stdin. Even a function may - use this form of redirection (see ). - The < operator at the end of the code block - accomplishes this. - - - Redirected <emphasis>while</emphasis> loop - &redir2; - - - - Alternate form of redirected <emphasis>while</emphasis> loop - &redir2a; - - - - Redirected <emphasis>until</emphasis> loop - &redir3; - - - - Redirected <emphasis>for</emphasis> loop - &redir4; - - - We can modify the previous example to also redirect the output of - the loop. - - - Redirected <emphasis>for</emphasis> loop (both - <filename>stdin</filename> and <filename>stdout</filename> - redirected) - &redir4a; - - - - Redirected <emphasis>if/then</emphasis> test - &redir5; - - - - Data file <quote>names.data</quote> for above examples - &namesdata; - - - Redirecting the stdout of a code - block has the effect of saving its output to a file. See . - - Here documents - are a special case of redirected code blocks. - - - - - - Applications - - Clever use of I/O redirection permits parsing and stitching - together snippets of command output (see ). This permits - generating report and log files. - - - Logging events - &logevents; - - - - - - - - - - - - Here Documents - - - Aldous Huxley, Island - Here and now, boys. - - - - - - << - - - special character - << - - - A here document is a special-purpose - code block. It uses a form of I/O - redirection to feed a command list to - an interactive program or a command, such as ftp, cat, - or the ex text editor. - - COMMAND <<InputComesFromHERE -... -InputComesFromHERE - - - A limit string delineates (frames) - the command list. The special symbol << designates - the limit string. This has the effect of redirecting the output - of a file into the stdin of the program - or command. It is similar to interactive-program < - command-file, where command-file - contains - - command #1 -command #2 -... - - The here document alternative looks - like this: - - #!/bin/bash -interactive-program <<LimitString -command #1 -command #2 -... -LimitString - - Choose a limit string sufficiently - unusual that it will not occur anywhere in the command list and - confuse matters. - - Note that here documents may sometimes - be used to good effect with non-interactive utilities and commands, - such as, for example, wall. - - - - <command>broadcast</command>: Sends message to everyone logged in - &ex70; - - - - Even such unlikely candidates as vi lend - themselves to here documents. - - - <command>dummyfile</command>: Creates a 2-line dummy file - &ex69; - - - - The above script could just as effectively have been implemented with - ex, rather than - vi. Here documents - containing a list of ex commands are common - enough to form their own category, known as ex - scripts. - - #!/bin/bash -# Replace all instances of "Smith" with "Jones" -#+ in files with a ".txt" filename suffix. - -ORIGINAL=Smith -REPLACEMENT=Jones - -for word in $(fgrep -l $ORIGINAL *.txt) -do - # ------------------------------------- - ex $word <<EOF - :%s/$ORIGINAL/$REPLACEMENT/g - :wq -EOF - # :%s is the "ex" substitution command. - # :wq is write-and-quit. - # ------------------------------------- -done - - - - Analogous to ex scripts are cat - scripts. - - - Multi-line message using <command>cat</command> - &ex71; - - - - The option to mark a here document limit string - (<<-LimitString) suppresses leading - tabs (but not spaces) in the output. This may be useful in making - a script more readable. - - - Multi-line message, with tabs suppressed - &ex71a; - - - - A here document supports parameter and - command substitution. It is therefore possible to pass different - parameters to the body of the here document, changing its output - accordingly. - - - Here document with parameter substitution - &ex71b; - - - This is a useful script containing a here document with - parameter substitution. - - - Upload a file pair to <quote>Sunsite</quote> incoming - directory - &ex72; - - - - Quoting or escaping the limit string at the - head of a here document disables parameter substitution within its - body. - - - Parameter substitution turned off - &ex71c; - - - Disabling parameter substitution permits outputting literal text. - Generating scripts or even program code is one use for this. - - - A script that generates another script - &generatescript; - - - - - - It is possible to set a variable from the output of a here document. - variable=$(cat <<SETVAR -This variable -runs over multiple lines. -SETVAR) - -echo "$variable" - - - - A here document can supply input to a function in the same - script. - - - Here documents and functions - &hf; - - - - It is possible to use : as a dummy command - accepting output from a here document. This, in effect, creates an - anonymous here document. - - - <quote>Anonymous</quote> Here Document - #!/bin/bash - -: <<TESTVARIABLES -${HOSTNAME?}${USER?}${MAIL?} # Print error message if one of the variables not set. -TESTVARIABLES - -exit 0 - - - - - A variation of the above technique permits commenting - out blocks of code. - - - Commenting out a block of code - &commentblock; - - - - Yet another twist of this nifty trick makes - self-documenting scripts possible. - - - A self-documenting script - &selfdocument; - - - Using a cat script is an - alternate way of accomplishing this. - - - DOC_REQUEST=70 - -if [ "$1" = "-h" -o "$1" = "--help" ] # Request help. -then # Use a "cat script" . . . - cat <<DOCUMENTATIONXX -List the statistics of a specified directory in tabular format. ---------------------------------------------------------------- -The command line parameter gives the directory to be listed. -If no directory specified or directory specified cannot be read, -then list the current working directory. - -DOCUMENTATIONXX -exit $DOC_REQUEST -fi - - - - See also for one more excellent example - of a self-documenting script. - - - Here documents create temporary files, but these - files are deleted after opening and are not accessible to - any other process. - - bash$ bash -c 'lsof -a -p $$ -d0' << EOF -> EOF -lsof 1213 bozo 0r REG 3,5 0 30386 /tmp/t1213-0-sh (deleted) - - - - - Some utilities will not work inside a - here document. - - - - - - The closing limit string, - on the final line of a here document, must start in the - first character position. There can - be no leading whitespace. Trailing - whitespace after the limit string likewise causes unexpected - behavior. The whitespace prevents the limit string from being - recognized. - - - - - #!/bin/bash - -echo "----------------------------------------------------------------------" - -cat <<LimitString -echo "This is line 1 of the message inside the here document." -echo "This is line 2 of the message inside the here document." -echo "This is the final line of the message inside the here document." - LimitString -#^^^^Indented limit string. Error! This script will not behave as expected. - -echo "----------------------------------------------------------------------" - -# These comments are outside the 'here document', -#+ and should not echo. - -echo "Outside the here document." - -exit 0 - -echo "This line had better not echo." # Follows an 'exit' command. - - - - - For those tasks too complex for a here - document, consider using the expect - scripting language, which is specifically tailored for feeding - input into interactive programs. - - - - Here Strings - - - - A here string can be considered as - a stripped-down form of a here document. - It consists of nothing more than COMMAND - <<<$WORD, where $WORD - is expanded and fed to the stdin of - COMMAND. - - - String="This is a string of words." - -read -r -a Words <<< "$String" -# The -a option to "read" -#+ assigns the resulting values to successive members of an array. - -echo "First word in String is: ${Words[0]}" # This -echo "Second word in String is: ${Words[1]}" # is -echo "Third word in String is: ${Words[2]}" # a -echo "Fourth word in String is: ${Words[3]}" # string -echo "Fifth word in String is: ${Words[4]}" # of -echo "Sixth word in String is: ${Words[5]}" # words. -echo "Seventh word in String is: ${Words[6]}" # (null) - # Past end of $String. - -# Thank you, Francisco Lobo, for the suggestion. - - - - Prepending a line to a file - &prependex; - - - - Parsing a mailbox - &mailboxgrep; - - - Exercise: Find other uses for here - strings. - - - - - - - - - - Recess Time - -
- - This bizarre little intermission gives the reader a chance to - relax and maybe laugh a bit. - - Fellow Linux user, greetings! You are reading something which - will bring you luck and good fortune. Just e-mail a copy of - this document to 10 of your friends. Before making the copies, - send a 100-line Bash script to the first person on the list - at the bottom of this letter. Then delete their name and add - yours to the bottom of the list. - - Don't break the chain! Make the copies within 48 hours. - Wilfred P. of Brooklyn failed to send out his ten copies and - woke the next morning to find his job description changed - to "COBOL programmer." Howard L. of Newport News sent - out his ten copies and within a month had enough hardware - to build a 100-node Beowulf cluster dedicated to playing - Tuxracer. Amelia V. of Chicago laughed - at this letter and broke the chain. Shortly thereafter, a fire - broke out in her terminal and she now spends her days writing - documentation for MS Windows. - - Don't break the chain! Send out your ten copies today! - - - Courtesy 'NIX "fortune cookies", with some - alterations and many apologies - - -
- -
- - - - + Advanced Topics At this point, we are ready to delve into certain of the difficult and unusual aspects of scripting. Along the way, we will attempt to push the envelope in various - ways and examine boundary conditions + ways and examine boundary conditions (what happens when we move into uncharted territory?). @@ -21460,12 +21466,12 @@ echo "Seventh word in String is: ${Words[6]}" # (null) An expression is a string of characters. Those characters having an interpretation above and beyond their literal - meaning are called metacharacters. A - quote symbol, for example, may denote speech by a person, - ditto, or a meta-meaning for the symbols + meaning are called metacharacters. + A quote symbol, for example, may denote speech by a person, + ditto, or a meta-meaning for the symbols that follow. Regular Expressions are sets of characters and/or metacharacters that match (or specify) patterns. - + A Regular Expression contains one or more of the following: @@ -21481,14 +21487,14 @@ echo "Seventh word in String is: ${Words[6]}" # (null) An anchor. These designate - (anchor) the position in the line of + (anchor) the position in the line of text that the RE is to match. For example, ^, and $ are anchors. Modifiers. These expand or narrow - (modify) the range of text the RE is + (modify) the range of text the RE is to match. Modifiers include the asterisk, brackets, and the backslash. @@ -21601,7 +21607,7 @@ exit 0 The dollar sign -- $ -- at the end of an RE matches the end of a line. - XXX$ matches XXX at the + XXX$ matches XXX at the end of a line. ^$ matches blank lines. @@ -22255,6 +22261,751 @@ echo a111b | gawk '/a1+b/' + + Here Documents + + + Aldous Huxley, Island + Here and now, boys. + + + + + + << + + + special character + << + + + A here document is a special-purpose + code block. It uses a form of I/O + redirection to feed a command list to + an interactive program or a command, such as ftp, cat, + or the ex text editor. + + COMMAND <<InputComesFromHERE +... +InputComesFromHERE + + + A limit string delineates (frames) + the command list. The special symbol << designates + the limit string. This has the effect of redirecting the output + of a file into the stdin of the program + or command. It is similar to interactive-program < + command-file, where command-file + contains + + command #1 +command #2 +... + + The here document alternative looks + like this: + + #!/bin/bash +interactive-program <<LimitString +command #1 +command #2 +... +LimitString + + Choose a limit string sufficiently + unusual that it will not occur anywhere in the command list and + confuse matters. + + Note that here documents may sometimes + be used to good effect with non-interactive utilities and commands, + such as, for example, wall. + + + + <command>broadcast</command>: Sends message to everyone logged in + &ex70; + + + + Even such unlikely candidates as vi lend + themselves to here documents. + + + <command>dummyfile</command>: Creates a 2-line dummy file + &ex69; + + + + The above script could just as effectively have been implemented with + ex, rather than + vi. Here documents + containing a list of ex commands are common + enough to form their own category, known as ex + scripts. + + #!/bin/bash +# Replace all instances of "Smith" with "Jones" +#+ in files with a ".txt" filename suffix. + +ORIGINAL=Smith +REPLACEMENT=Jones + +for word in $(fgrep -l $ORIGINAL *.txt) +do + # ------------------------------------- + ex $word <<EOF + :%s/$ORIGINAL/$REPLACEMENT/g + :wq +EOF + # :%s is the "ex" substitution command. + # :wq is write-and-quit. + # ------------------------------------- +done + + + + Analogous to ex scripts are cat + scripts. + + + Multi-line message using <command>cat</command> + &ex71; + + + + The option to mark a here document limit string + (<<-LimitString) suppresses leading + tabs (but not spaces) in the output. This may be useful in making + a script more readable. + + + Multi-line message, with tabs suppressed + &ex71a; + + + + A here document supports parameter and + command substitution. It is therefore possible to pass different + parameters to the body of the here document, changing its output + accordingly. + + + Here document with parameter substitution + &ex71b; + + + This is a useful script containing a here document with + parameter substitution. + + + Upload a file pair to <quote>Sunsite</quote> incoming + directory + &ex72; + + + + Quoting or escaping the limit string at the + head of a here document disables parameter substitution within its + body. + + + Parameter substitution turned off + &ex71c; + + + Disabling parameter substitution permits outputting literal text. + Generating scripts or even program code is one use for this. + + + A script that generates another script + &generatescript; + + + + + + It is possible to set a variable from the output of a here document. + variable=$(cat <<SETVAR +This variable +runs over multiple lines. +SETVAR) + +echo "$variable" + + + + A here document can supply input to a function in the same + script. + + + Here documents and functions + &hf; + + + + It is possible to use : as a dummy command + accepting output from a here document. This, in effect, creates an + anonymous here document. + + + <quote>Anonymous</quote> Here Document + #!/bin/bash + +: <<TESTVARIABLES +${HOSTNAME?}${USER?}${MAIL?} # Print error message if one of the variables not set. +TESTVARIABLES + +exit 0 + + + + + A variation of the above technique permits commenting + out blocks of code. + + + Commenting out a block of code + &commentblock; + + + + Yet another twist of this nifty trick makes + self-documenting scripts possible. + + + A self-documenting script + &selfdocument; + + + Using a cat script is an + alternate way of accomplishing this. + + + DOC_REQUEST=70 + +if [ "$1" = "-h" -o "$1" = "--help" ] # Request help. +then # Use a "cat script" . . . + cat <<DOCUMENTATIONXX +List the statistics of a specified directory in tabular format. +--------------------------------------------------------------- +The command line parameter gives the directory to be listed. +If no directory specified or directory specified cannot be read, +then list the current working directory. + +DOCUMENTATIONXX +exit $DOC_REQUEST +fi + + + + See also for one more excellent example + of a self-documenting script. + + + Here documents create temporary files, but these + files are deleted after opening and are not accessible to + any other process. + + bash$ bash -c 'lsof -a -p $$ -d0' << EOF +> EOF +lsof 1213 bozo 0r REG 3,5 0 30386 /tmp/t1213-0-sh (deleted) + + + + + Some utilities will not work inside a + here document. + + + + + + The closing limit string, + on the final line of a here document, must start in the + first character position. There can + be no leading whitespace. Trailing + whitespace after the limit string likewise causes unexpected + behavior. The whitespace prevents the limit string from being + recognized. + + + + + #!/bin/bash + +echo "----------------------------------------------------------------------" + +cat <<LimitString +echo "This is line 1 of the message inside the here document." +echo "This is line 2 of the message inside the here document." +echo "This is the final line of the message inside the here document." + LimitString +#^^^^Indented limit string. Error! This script will not behave as expected. + +echo "----------------------------------------------------------------------" + +# These comments are outside the 'here document', +#+ and should not echo. + +echo "Outside the here document." + +exit 0 + +echo "This line had better not echo." # Follows an 'exit' command. + + + + + For those tasks too complex for a here + document, consider using the expect + scripting language, which is specifically tailored for feeding + input into interactive programs. + + + + Here Strings + + + + A here string can be considered as + a stripped-down form of a here document. + It consists of nothing more than COMMAND + <<<$WORD, where $WORD + is expanded and fed to the stdin of + COMMAND. + + + String="This is a string of words." + +read -r -a Words <<< "$String" +# The -a option to "read" +#+ assigns the resulting values to successive members of an array. + +echo "First word in String is: ${Words[0]}" # This +echo "Second word in String is: ${Words[1]}" # is +echo "Third word in String is: ${Words[2]}" # a +echo "Fourth word in String is: ${Words[3]}" # string +echo "Fifth word in String is: ${Words[4]}" # of +echo "Sixth word in String is: ${Words[5]}" # words. +echo "Seventh word in String is: ${Words[6]}" # (null) + # Past end of $String. + +# Thank you, Francisco Lobo, for the suggestion. + + + + Prepending a line to a file + &prependex; + + + + Parsing a mailbox + &mailboxgrep; + + + Exercise: Find other uses for here + strings. + + + + + + + + + + I/O Redirection + + + + There are always three default files + open, stdin (the keyboard), + stdout (the screen), and + stderr (error messages output to the + screen). These, and any other open files, can be redirected. + Redirection simply means capturing output from a file, command, + program, script, or even code block within a script (see and ) and sending it as + input to another file, command, program, or script. + + Each open file gets assigned a file descriptor. + + A file descriptor + is simply a number that the operating system assigns + to an open file to keep track of it. Consider it + a simplified version of a file pointer. It is + analogous to a file handle in + C. + + The file descriptors for stdin, + stdout, and stderr are + 0, 1, and 2, respectively. For opening additional files, there + remain descriptors 3 to 9. It is sometimes useful to assign one of + these additional file descriptors to stdin, + stdout, or stderr + as a temporary duplicate link. + Using file + descriptor 5 might cause problems. + When Bash creates a child process, as with exec, the child inherits + fd 5 (see Chet Ramey's archived e-mail, + SUBJECT: RE: File descriptor 5 is held open). + Best leave this particular fd alone. + This simplifies restoration to normal after complex redirection + and reshuffling (see ). + + + + COMMAND_OUTPUT > + # Redirect stdout to a file. + # Creates the file if not present, otherwise overwrites it. + + ls -lR > dir-tree.list + # Creates a file containing a listing of the directory tree. + + : > filename + # The > truncates file "filename" to zero length. + # If file not present, creates zero-length file (same effect as 'touch'). + # The : serves as a dummy placeholder, producing no output. + + > filename + # The > truncates file "filename" to zero length. + # If file not present, creates zero-length file (same effect as 'touch'). + # (Same result as ": >", above, but this does not work with some shells.) + + COMMAND_OUTPUT >> + # Redirect stdout to a file. + # Creates the file if not present, otherwise appends to it. + + + # Single-line redirection commands (affect only the line they are on): + # -------------------------------------------------------------------- + + 1>filename + # Redirect stdout to file "filename." + 1>>filename + # Redirect and append stdout to file "filename." + 2>filename + # Redirect stderr to file "filename." + 2>>filename + # Redirect and append stderr to file "filename." + &>filename + # Redirect both stdout and stderr to file "filename." + + M>N + # "M" is a file descriptor, which defaults to 1, if not explicitly set. + # "N" is a filename. + # File descriptor "M" is redirect to file "N." + M>&N + # "M" is a file descriptor, which defaults to 1, if not set. + # "N" is another file descriptor. + + #============================================================================== + + # Redirecting stdout, one line at a time. + LOGFILE=script.log + + echo "This statement is sent to the log file, \"$LOGFILE\"." 1>$LOGFILE + echo "This statement is appended to \"$LOGFILE\"." 1>>$LOGFILE + echo "This statement is also appended to \"$LOGFILE\"." 1>>$LOGFILE + echo "This statement is echoed to stdout, and will not appear in \"$LOGFILE\"." + # These redirection commands automatically "reset" after each line. + + + + # Redirecting stderr, one line at a time. + ERRORFILE=script.errors + + bad_command1 2>$ERRORFILE # Error message sent to $ERRORFILE. + bad_command2 2>>$ERRORFILE # Error message appended to $ERRORFILE. + bad_command3 # Error message echoed to stderr, + #+ and does not appear in $ERRORFILE. + # These redirection commands also automatically "reset" after each line. + #============================================================================== + + + + 2>&1 + # Redirects stderr to stdout. + # Error messages get sent to same place as standard output. + + i>&j + # Redirects file descriptor i to j. + # All output of file pointed to by i gets sent to file pointed to by j. + + >&j + # Redirects, by default, file descriptor 1 (stdout) to j. + # All stdout gets sent to file pointed to by j. + + 0< FILENAME + < FILENAME + # Accept input from a file. + # Companion command to >, and often used in combination with it. + # + # grep search-word <filename + + + [j]<>filename + # Open file "filename" for reading and writing, and assign file descriptor "j" to it. + # If "filename" does not exist, create it. + # If file descriptor "j" is not specified, default to fd 0, stdin. + # + # An application of this is writing at a specified place in a file. + echo 1234567890 > File # Write string to "File". + exec 3<> File # Open "File" and assign fd 3 to it. + read -n 4 <&3 # Read only 4 characters. + echo -n . >&3 # Write a decimal point there. + exec 3>&- # Close fd 3. + cat File # ==> 1234.67890 + # Random access, by golly. + + + + | + # Pipe. + # General purpose process and command chaining tool. + # Similar to >, but more general in effect. + # Useful for chaining commands, scripts, files, and programs together. + cat *.txt | sort | uniq > result-file + # Sorts the output of all the .txt files and deletes duplicate lines, + # finally saves results to result-file. + + + Multiple instances of input and output redirection + and/or pipes can be combined in a single command + line. + + command < input-file > output-file + +command1 | command2 | command3 > output-file + See and . + + + Multiple output streams may be redirected to one file. + + ls -yz >> command.log 2>&1 +# Capture result of illegal options "yz" in file "command.log." +# Because stderr is redirected to the file, +#+ any error messages will also be there. + +# Note, however, that the following does *not* give the same result. +ls -yz 2>&1 >> command.log +# Outputs an error message and does not write to file. + +# If redirecting both stdout and stderr, +#+ the order of the commands makes a difference. + + + + + <anchor id="cfd">Closing File Descriptors + + + n<&- + + Close input file descriptor + n. + + + + + 0<&- + <&- + + Close stdin. + + + + + n>&- + + Close output file descriptor n. + + + + + 1>&- + >&- + + Close stdout. + + + + + + + Child processes inherit open file descriptors. This is why pipes + work. To prevent an fd from being inherited, close it. + # Redirecting only stderr to a pipe. + +exec 3>&1 # Save current "value" of stdout. +ls -l 2>&1 >&3 3>&- | grep bad 3>&- # Close fd 3 for 'grep' (but not 'ls'). +# ^^^^ ^^^^ +exec 3>&- # Now close it for the remainder of the script. + +# Thanks, S.C. + + + For a more detailed introduction to I/O redirection see + . + + + + + Using <command>exec</command> + + + + + An exec <filename command redirects + stdin to a file. From that point on, all + stdin comes from that file, rather than + its normal source (usually keyboard input). This provides a + method of reading a file line by line and possibly parsing + each line of input using sed + and/or awk. + + + Redirecting <filename>stdin</filename> using + <command>exec</command> + &redir1; + + + Similarly, an exec >filename + command redirects stdout to a designated + file. This sends all command output that would normally go + to stdout to that file. + + + + exec N > filename affects the entire + script or current shell. Redirection in + the PID of the script or shell + from that point on has changed. However . . . + + + N > filename affects only the newly-forked process, + not the entire script or shell. + + Thank you, Ahmed Darwish, for pointing this out. + + + + + + Redirecting <filename>stdout</filename> using + <command>exec</command> + &reassignstdout; + + + + Redirecting both <filename>stdin</filename> and + <filename>stdout</filename> in the same script with + <command>exec</command> + &upperconv; + + + I/O redirection is a clever way of avoiding the dreaded inaccessible variables within a subshell + problem. + + + Avoiding a subshell + &avoidsubshell; + + + + + + + + + Redirecting Code Blocks + + Blocks of code, such as while, until, and for loops, even if/then test blocks can also incorporate + redirection of stdin. Even a function may + use this form of redirection (see ). + The < operator at the end of the code block + accomplishes this. + + + Redirected <firstterm>while</firstterm> loop + &redir2; + + + + Alternate form of redirected <firstterm>while</firstterm> loop + &redir2a; + + + + Redirected <firstterm>until</firstterm> loop + &redir3; + + + + Redirected <firstterm>for</firstterm> loop + &redir4; + + + We can modify the previous example to also redirect the output of + the loop. + + + Redirected <firstterm>for</firstterm> loop (both + <filename>stdin</filename> and <filename>stdout</filename> + redirected) + &redir4a; + + + + Redirected <firstterm>if/then</firstterm> test + &redir5; + + + + Data file <quote>names.data</quote> for above examples + &namesdata; + + + Redirecting the stdout of a code + block has the effect of saving its output to a file. See . + + Here documents + are a special case of redirected code blocks. + + + + + + Applications + + Clever use of I/O redirection permits parsing and stitching + together snippets of command output (see ). This permits + generating report and log files. + + + Logging events + &logevents; + + + + + + + + + + + Subshells @@ -22269,7 +23020,7 @@ echo a111b | gawk '/a1+b/' xterm window. A shell script can also launch subprocesses. These - subshells let the script do + subshells let the script do parallel processing, in effect executing multiple subtasks simultaneously. @@ -22414,7 +23165,7 @@ fi Running a script or portion of a script in - restricted mode disables certain commands that + restricted mode disables certain commands that would otherwise be available. This is a security measure intended to limit the privileges of the script user and to minimize possible damage from running the script. @@ -22472,8 +23223,8 @@ fi - Invoking exec to substitute a different - process for the shell. + Invoking exec to substitute + a different process for the shell. @@ -22920,7 +23671,7 @@ exit # Invokes "exit ()" function, not "exit" builtin. Terminates a function. A return command The return command is a Bash builtin. - optionally takes an integer + optionally takes an integer argument, which is returned to the calling script as the exit status of the function, and this exit status is assigned to the variable block of code in which it appears. It has local scope. In - a function, a local variable has + a function, a local variable has meaning only within that function block. @@ -23160,7 +23911,7 @@ Function () # This doesn't work. Before a function is called, all variables declared within the function are invisible outside the body of the function, not just those explicitly declared - as local. + as local. #!/bin/bash func () @@ -23192,7 +23943,7 @@ echo "global_var = $global_var" # global_var = 37 Herbert Mayer - defines recursion as + defines recursion as . . . expressing an algorithm by using a simpler version of that same algorithm . . . A recursive function is one that calls itself. @@ -23274,14 +24025,14 @@ exit 0 # This script will not exit normally. alias - A Bash alias is essentially nothing more than - a keyboard shortcut, an abbreviation, a means of avoiding - typing a long command sequence. If, for example, we include - alias lm="ls -l | more" in the ~/.bashrc file, - then each lm typed at the command - line will automatically be replaced by a ls -l | - more. This can save a great deal of typing at the + A Bash alias is essentially nothing + more than a keyboard shortcut, an abbreviation, a means of + avoiding typing a long command sequence. If, for example, + we include alias lm="ls -l | more" in + the ~/.bashrc + file, then each lm typed at the + command line will automatically be replaced by a ls -l + | more. This can save a great deal of typing at the command line and avoid having to remember complex combinations of commands and options. Setting alias rm="rm -i" (interactive mode delete) may save a good deal of grief, since @@ -23307,7 +24058,7 @@ exit 0 # This script will not exit normally. The unalias command removes a previously - set alias. + set alias. <command>unalias</command>: Setting and unsetting an alias @@ -23394,12 +24145,12 @@ drwxr-xr-x 40 bozo bozo 2048 Feb 6 14:04 .. - Of course, an and list can also - set variables to a default value. - arg1=$@ # Set $arg1 to command line arguments, if any. - -[ -z "$arg1" ] && arg1=DEFAULT - # Set to DEFAULT if not specified on command line. + Of course, an and list can also + set variables to a default value. + arg1=$@ && [ -z "$arg1" ] && arg1=DEFAULT + + # Set $arg1 to command line arguments, if any. + # But . . . set to DEFAULT if not specified on command line. @@ -23601,6 +24352,21 @@ echo ${#string[@]} # 1 array2=( "${array1[@]}" ) # or array2="${array1[@]}" +# +# However, this fails with "sparse" arrays, +#+ arrays with holes (missing elements) in them, +#+ as Jochen DeSmet points out. +# ------------------------------------------ + array1[0]=0 +# array1[1] not assigned + array1[2]=2 + array2=( "${array1[@]}" ) # Copy it? + +echo ${array2[0]} # 0 +echo ${array2[2]} # (null), should be 2 +# ------------------------------------------ + + # Adding an element to an array. array=( "${array[@]}" "new element" ) @@ -23679,7 +24445,7 @@ echo $element_count # 8 An old friend: - <emphasis>The Bubble Sort</emphasis> + The Bubble Sort &bubble; @@ -23726,14 +24492,15 @@ exit 0 -- - Arrays enable implementing a shell script version of the Sieve of - Eratosthenes. Of course, a resource-intensive application of this - nature should really be written in a compiled language, such as C. It - runs excruciatingly slowly as a script. + Arrays enable implementing a shell script version of the + Sieve of Eratosthenes. Of course, a + resource-intensive application of this nature should really be + written in a compiled language, such as C. It runs excruciatingly + slowly as a script. Complex array application: - <emphasis>Sieve of Eratosthenes</emphasis> + Sieve of Eratosthenes &ex68; @@ -23774,8 +24541,8 @@ exit 0 A two-dimensional array is essentially equivalent to a one-dimensional one, but with additional addressing modes - for referencing and manipulating the individual elements - by row and column + for referencing and manipulating the individual elements by + row and column position. For an even more elaborate example of simulating a @@ -23783,9 +24550,10 @@ exit 0 -- - For yet another interesting script using arrays, see: + For more interesting scripts using arrays, see: - + and @@ -23808,7 +24576,7 @@ exit 0 <filename class="directory">/dev</filename> The /dev directory - contains entries for the physical devices + contains entries for the physical devices that may or may not be present in the hardware. The entries in /dev @@ -23835,14 +24603,14 @@ exit 0 Among other things, the /dev directory also - contains loopback devices, such as + contains loopback devices, such as /dev/loop0. A loopback device is a gimmick that allows an ordinary file to be accessed as if it were a block device. - A block device reads and/or - writes data in chunks, or blocks, in contrast to a - character device, which acesses data + A block device reads + and/or writes data in chunks, or blocks, in contrast to a + character device, which acesses data in character units. Examples of block devices are a hard drive and CD ROM drive. An example of a character device is a keyboard. @@ -23868,11 +24636,13 @@ exit 0 Of course, the mount point /mnt/flashdrive must exist. If not, - then, as root, mkdir /mnt/flashdrive. - To actually mount the drive, use the following command: + then, as root, mkdir + /mnt/flashdrive. + To actually mount the drive, use the following command: mount /mnt/flashdrive Newer Linux distros automount flash drives in the - /media directory. + /media + directory. /dev/sda1 /mnt/flashdrive auto noauto,user,noatime 0 0 @@ -23883,14 +24653,18 @@ exit 0 When executing a command on a /dev/tcp/$host/$port pseudo-device file, Bash - opens a TCP connection to the associated socket. - - A socket is a communications - node associated with a specific I/O port. It permits data - transfer between hardware devices on the same machine, - between machines on the same network, between machines - across different networks, and, of course, between machines - at different locations on the Internet. + opens a TCP connection to the associated + socket. + + A socket is a + communications node associated with a specific I/O + port. (This is analogous to a hardware + socket, or receptacle, + for a connecting cable.) It permits data transfer between + hardware devices on the same machine, between machines + on the same network, between machines across different + networks, and, of course, between machines at different + locations on the Internet. @@ -23930,7 +24704,7 @@ exit 0 The /proc directory is actually a pseudo-filesystem. The files in /proc mirror currently running - system and kernel processes and contain + system and kernel processes and contain information and statistics about them. @@ -24291,7 +25065,7 @@ rm *' '* Even better is an echo that echoes - only when debug is on. + only when debug is on. ### debecho (debug-echo), by Stefano Falsetto ### ### Will echo passed parameters only if DEBUG is set to a value. ### @@ -24401,7 +25175,7 @@ debecho $Whatever # (Will not echo.) useful for debugging. A - signal is simply a message + signal is simply a message sent to a process, either by the kernel or another process, telling it to take some specified action (usually to terminate). For example, hitting a @@ -24515,7 +25289,7 @@ trap 'echo "Control-C disabled."' 2 # Exact same effect as above. - To disable an option within a script, + To disable an option within a script, use set +o option-name or set +option-abbrev. @@ -24633,7 +25407,7 @@ trap 'echo "Control-C disabled."' 2 interactive - Script runs in interactive mode + Script runs in interactive mode @@ -24643,7 +25417,7 @@ trap 'echo "Control-C disabled."' 2 (none) - Invoke the Option-Name + Invoke the Option-Name option @@ -24653,6 +25427,14 @@ trap 'echo "Control-C disabled."' 2 conform to POSIX standard. + + + pipe failure + Causes a pipeline to return the exit status of + the last command in the pipe that returned a non-zero + return value. + privileged @@ -24661,7 +25443,7 @@ trap 'echo "Control-C disabled."' 2 restricted - Script runs in restricted + Script runs in restricted mode (see ). @@ -24701,7 +25483,7 @@ trap 'echo "Control-C disabled."' 2 (none) Unset positional parameters. - If arguments given (-- arg1 arg2), + If arguments given (-- arg1 arg2), positional parameters set to arguments. @@ -24818,7 +25600,7 @@ if [ $a -le 5] # if [ $a -le 5 ] is correct. Assuming uninitialized variables (variables before a value is assigned to them) are zeroed out. An - uninitialized variable has a value of null, + uninitialized variable has a value of null, not zero. @@ -24832,9 +25614,10 @@ echo "uninitialized_var = $uninitialized_var" - Mixing up = and -eq in - a test. Remember, = is for comparing literal - variables and -eq for integers. + Mixing up = and + -eq in a test. Remember, + = is for comparing literal variables + and -eq for integers. if [ "$a" = 273 ] # Is $a an integer or string? @@ -24892,7 +25675,7 @@ fi # Aborts with an error message. cannot invoke a command from the command line, then putting it into a script will likewise fail. Try changing the attributes of the command in question, perhaps even setting the suid bit - (as root, of course). + (as root, of course). @@ -25140,8 +25923,8 @@ find $HOME -type f -atime +30 -size 100k | { Using suid commands within scripts is risky, as it may compromise system security. - Setting the suid permission on - the script itself has no effect. + Setting the suid + permission on the script itself has no effect. @@ -25250,7 +26033,7 @@ cleanup_pfiles $projectdir exit 0 - Be sure to put the #!/bin/bash at the + Be sure to put the #!/bin/bash at the beginning of the first line of the script, preceding any comment headers. @@ -25436,11 +26219,11 @@ if COMMAND Interactive and non-interactive shells and scripts - An interactive shell reads commands from - user input on a tty. Among other things, - such a shell reads startup files on activation, displays - a prompt, and enables job control by default. The user can - interact with the shell. + An interactive shell reads + commands from user input on a tty. Among + other things, such a shell reads startup files on activation, + displays a prompt, and enables job control by default. The + user can interact with the shell. A shell running a script is always a non-interactive shell. All the same, the script can still access its @@ -25461,11 +26244,11 @@ exit 0 # This example script, and much of the above explanation supplied by # Stéphane Chazelas (thanks again). - Let us consider an interactive script - to be one that requires input from the user, usually with - read statements (see ). Real life is actually a - bit messier than that. For now, assume an interactive script + Let us consider an interactive + script to be one that requires input from the user, usually + with read statements (see ). Real life is actually a + bit messier than that. For now, assume an interactive script is bound to a tty, a script that a user has invoked from the console or an xterm. @@ -25488,7 +26271,7 @@ exit 0 If a script needs to test whether it is running in an interactive shell, it is simply a matter of finding - whether the prompt variable, prompt variable, $PS1 is set. (If the user is being prompted for input, then the script needs to display a prompt.) @@ -25725,18 +26508,18 @@ test "$city" \< Paris && echo "Yes, Paris is greater than $city" # Greater ASCI The simplest, and perhaps most useful ANSI escape sequence is bold text, \033[1m ... \033[0m. The - \033 represents an escape, - the [1 turns on the bold attribute, while the - [0 switches it off. The m terminates - each term of the escape sequence. + \033 represents an escape, the [1 turns on the + bold attribute, while the [0 switches it off. The + m terminates each term of the escape sequence. bash$ echo -e "\033[1mThis is bold text.\033[0m" A similar escape sequence switches on the underline - attribute (on an rxvt and an - aterm). + attribute (on an rxvt and an + aterm). bash$ echo -e "\033[4mThis is underlined text.\033[0m" @@ -25762,7 +26545,7 @@ test "$city" \< Paris && echo "Yes, Paris is greater than $city" # Greater ASCI It's usually advisable to set the - bold attribute for light-colored foreground + bold attribute for light-colored foreground text. The tput sgr0 restores the @@ -25798,7 +26581,7 @@ test "$city" \< Paris && echo "Yes, Paris is greater than $city" # Greater ASCI The numbers in the following table work for an - rxvt terminal. Results may vary for other + rxvt terminal. Results may vary for other terminal emulators. @@ -26002,8 +26785,8 @@ echo $title | cat - $file >$file.new A shell script may act as an embedded command inside - another shell script, a Tcl or - wish script, or even a Tcl or + wish script, or even a Makefile. It can be invoked as an external shell command in a C program using the system() call, i.e., @@ -26287,9 +27070,9 @@ echo "$newstring" # Every sentence should start with a capital letter.< Passing an array involves loading the space-separated elements of the array into a variable with command substitution. Getting - an array back as the return value from - a function uses the previously mentioned strategem of - echoing the array in the function, + an array back as the return value from a + function uses the previously mentioned strategem of echoing the array in the function, then invoking command substitution and the ( ... ) operator to assign it to an array. @@ -26420,17 +27203,17 @@ fi It would be nice to be able to invoke X-Windows widgets - from a shell script. There happen to exist - several packages that purport to do so, namely - Xscript, Xmenu, - and widtools. The first two of - these no longer seem to be maintained. Fortunately, it is - still possible to obtain widtools Xscript, + Xmenu, and widtools. + The first two of these no longer seem + to be maintained. Fortunately, it is still + possible to obtain widtools here. - The widtools (widget tools) - package requires the XForms library to + The widtools (widget tools) + package requires the XForms library to be installed. Additionally, the Makefile needs some judicious editing before the package will build on a typical Linux @@ -26440,11 +27223,11 @@ fi - The dialog family of tools offers a method + The dialog family of tools offers a method of calling dialog widgets from a shell script. The - original dialog utility works in a text - console, but its successors, gdialog, - Xdialog, and kdialog + original dialog utility works in a text + console, but its successors, gdialog, + Xdialog, and kdialog use X-Windows-based widget sets. @@ -26453,14 +27236,19 @@ fi For other methods of scripting with widgets, try - Tk or wish - (Tcl derivatives), - PerlTk (Perl with Tk extensions), - tksh (ksh with Tk extensions), - XForms4Perl (Perl with XForms - extensions), Gtk-Perl (Perl with Gtk - extensions), or PyQt (Python with - Qt extensions). + Tk or wish + (Tcl derivatives), + PerlTk (Perl + with Tk extensions), + tksh (ksh + with Tk extensions), + XForms4Perl + (Perl with + XForms extensions), + Gtk-Perl (Perl + with Gtk extensions), or + PyQt (Python + with Qt extensions). @@ -26468,12 +27256,12 @@ fi For doing multiple revisions on a complex script, use the - rcs Revision Control System package. + rcs Revision Control System package. Among other benefits of this is automatically updated ID header tags. The co command in - rcs does a parameter replacement of + rcs does a parameter replacement of certain reserved key words, for example, replacing #$Id$ in a script with something like: #$Id$ @@ -26494,10 +27282,11 @@ fi Infected Shell Scripts A brief warning about script security is appropriate. - A shell script may contain a worm, - trojan, or even a virus. - For that reason, never run as root a script (or permit it - to be inserted into the system startup scripts in worm, + trojan, or even a + virus. For that reason, never run + as root a script (or permit it to + be inserted into the system startup scripts in /etc/rc.d) unless you have obtained said script from a trusted source or you have carefully analyzed it to make certain it does nothing harmful. @@ -26505,7 +27294,7 @@ fi Various researchers at Bell Labs and other sites, including M. Douglas McIlroy, Tom Duff, and Fred Cohen have investigated the implications of shell script viruses. They conclude that it is - all to easy for even a novice, a script kiddie, + all too easy for even a novice, a script kiddie, to write one. See Marius van Oers' article, Unix @@ -26648,7 +27437,7 @@ fi - The current version of Bash, the one + The current version of Bash, the one you have running on your machine, is version 2.xx.y or 3.xx.y. bash$ echo $BASH_VERSION 2.05.b.0(1)-release @@ -26703,9 +27492,11 @@ fi + A new, more generalized {a..z} brace expansion operator. - #!/bin/bash + linkend="braceexpref">brace expansion operator. + + #!/bin/bash for i in {1..10} # Simpler and more straightforward than @@ -26717,16 +27508,30 @@ done echo # 1 2 3 4 5 6 7 8 9 10 - - + + +# Or just . . . + +echo {a..z} # a b c d e f g h i j k l m n o p q r s t u v w x y z +echo {z..a} # z y x w v u t s r q p o n m l k j i h g f e d c b a + # Works backwards, too. +echo {3..-2} # 3 2 1 0 -1 -2 +echo {X..d} # X Y Z [ ] ^ _ ` a b c d + # Shows (some of) the the ASCII characters between Z and a, + #+ but don't rely on this type of behavior because . . . +echo {]..a} # {]..a} + # Why? + + The ${!array[@]} operator, which expands to all the indices of a given array. - #!/bin/bash + linkend="arrayref">array. + + #!/bin/bash Array=(element-zero element-one element-two element-three) @@ -26744,10 +27549,11 @@ do # element-three # # All the elements in Array. -done - +done + + The =~ Regular @@ -26794,6 +27600,18 @@ fi + + + The new option is + useful for debugging pipes. If + this option is set, then the exit status of a pipe + is the exit status of the last command in the pipe to + fail (return a non-zero value), rather + than the actual final command in the pipe. + See . + + @@ -26858,7 +27676,7 @@ echo $a # 6 - + @@ -26988,6 +27806,12 @@ echo $a # 6 <g>? + + Update: upgraded to a A31 Thinkpad (P4-1.6, + 512 meg RAM) running FC5. No longer starving, and no longer + soliciting donations <g>. + + @@ -27149,10 +27973,11 @@ echo $a # 6 Kenny Stauffer, Filip Moritz, Andrzej Stefanski, Daniel Albers, Stefano Palmeri, Nils Radtke, Jeroen Domburg, Alfredo Pironti, Phil Braham, Bruno de Oliveira Schneider, Stefano Falsetto, - Chris Morgan, Walter Dnes, Linc Fessenden, Michael Iatrou, Pharis - Monalo, Jesse Gough, Fabian Kreutz, Mark Norman, Harald Koenig, - Peter Knowles, Francisco Lobo, Mariusz Gniazdowski, Tedman Eng, - Achmed Darwish, Andreas Kühne, and David Lawyer (himself + Chris Morgan, Walter Dnes, Linc Fessenden, Michael Iatrou, + Pharis Monalo, Jesse Gough, Fabian Kreutz, Mark Norman, Harald + Koenig, Peter Knowles, Francisco Lobo, Mariusz Gniazdowski, + Tedman Eng, Jochen DeSmet, Oliver Beckstein, Achmed Darwish, + Omair Eshkenazi, Andreas Kühne, and David Lawyer (himself an author of four HOWTOs).My gratitude to Chet @@ -27868,9 +28693,9 @@ echo $a # 6 William Park has been working on a project - to incorporate certain Awk and Python - features into Bash. Among these is a - gdbm interface. He has released Awk and + Python features into Bash. Among these is + a gdbm interface. He has released bashdiff on Freshmeat.net. He has an - The manpages for bash and - bash2, date, - expect, expr, - find, grep, - gzip, ln, - patch, tar, - tr, bc, - xargs. The texinfo documentation - on bash, dd, + The manpages for + bash and bash2, + date, expect, + expr, find, + grep, gzip, + ln, patch, + tar, tr, + bc, xargs. The texinfo + documentation on bash, dd, m4, gawk, and sed. @@ -28048,8 +28873,10 @@ echo $a # 6 +++ The following two scripts are by Mark Moraes of the University - of Toronto. See the enclosed file Moraes-COPYRIGHT - for permissions and restrictions. + of Toronto. See the file Moraes-COPYRIGHT + for permissions and restrictions. This file is included in the + combined HTML/source tarball + of the ABS Guide. <command>behead</command>: Removing mail and news message headers @@ -28109,7 +28936,7 @@ echo $a # 6</programlisting> <para>Noah Friedman gave permission to use his <emphasis>string function</emphasis> script, which essentially reproduces some of the - C-library string manipulation functions.</para> + <firstterm>C</firstterm>-library string manipulation functions.</para> <example id="string"> <title><command>string functions</command>: C-like string functions @@ -28149,6 +28976,14 @@ echo $a # 6 &hashexample; + An example illustrating the mechanics of hashing, + but from a different point of view. + + + More on hash functions + &hashex2; + + Now for a script that installs and mounts those cute USB keychain solid-state hard drives. @@ -28296,7 +29131,7 @@ echo $a # 6 Flags passed to script (using - set) + set) @@ -28430,8 +29265,8 @@ echo $a # 6 * If within a - double-bracket [[ ... ]] test construct, - then no escape \ is + double-bracket [[ ... ]] test construct, + then no escape \ is needed.
@@ -28456,49 +29291,49 @@ echo $a # 6 - File is a regular file + File is a regular file - File is a directory + File is a directory - File has read + File has read permission - File is a symbolic link + File is a symbolic link - File has write + File has write permission - File is a symbolic link + File is a symbolic link - File has execute + File has execute permission - File is a block device + File is a block device - File is a character device + File is a character device - sgid flag set + sgid flag set - File is a pipe + File is a pipe - suid flag set + suid flag set @@ -28510,7 +29345,7 @@ echo $a # 6 File is associated with a - terminal + terminal @@ -28529,11 +29364,11 @@ echo $a # 6 - Group id of file same as + Group id of file same as yours - Files F1 and F2 are hard links + Files F1 and F2 are hard links to the same file * @@ -28547,7 +29382,7 @@ echo $a # 6
- * Binary operator + * Binary operator (requires two operands). @@ -28767,7 +29602,7 @@ echo $a # 6 * Where $substring is a - regular expression. + regular expression. @@ -28784,19 +29619,19 @@ echo $a # 6 - Brackets + Brackets - Test construct + Test construct - Extended test construct + Extended test construct - Array initialization + Array initialization @@ -28804,11 +29639,11 @@ echo $a # 6 - Curly Brackets + Curly Brackets - Parameter substitution + Parameter substitution @@ -28816,16 +29651,26 @@ echo $a # 6 - Block of code + Block of code - Brace expansion + Brace expansion + + + + Extended brace expansion + + + + Text replacement, after find and xargs - Parentheses + Parentheses @@ -28851,7 +29696,7 @@ echo $a # 6 - Double Parentheses + Double Parentheses @@ -28863,7 +29708,7 @@ echo $a # 6 - Quoting + Quoting @@ -28875,11 +29720,12 @@ echo $a # 6 - Back Quotes + Back Quotes - Execute command in subshell and assign result to variable + Execute command in subshell and assign result + to variable @@ -28936,7 +29782,7 @@ echo $a # 6 sed is usually one of several tool components in a pipe.
Sed determines which lines of its input that it will - operate on from the address range passed + operate on from the address range passed to it. If no address range is specified, the default is all lines. @@ -29005,8 +29851,8 @@ echo $a # 6 Unless the - (global) operator is appended to a - substitute command, the substitution + (global) operator is appended to a + substitute command, the substitution operates only on the first instance of a pattern match within each line. @@ -29118,8 +29964,8 @@ pattern=BEGIN A backslash forces the sed replacement command to continue on to the next line. This has the effect of - using the newline at the end of the first - line as the replacement string. + using the newline at the end of the first + line as the replacement string. s/^ */\ /g @@ -29214,8 +30060,8 @@ awk '{print $1 $5 $6}' $filename scripts, though a bit more flexibly. { total += ${column_number} } - This adds the value of column_number to - the running total of total. Finally, to print + This adds the value of column_number to + the running total of total>. Finally, to print total, there is an END command block, executed after the script has processed all its input. END { print total } @@ -29379,11 +30225,11 @@ awk '{print $1 $5 $6}' $filename linkend="tmdin">. Issuing a $? from - the command line after a shell script exits gives results - consistent with the table above only from the Bash or - sh prompt. Running the C-shell or - tcsh may give different values in some - cases. + the command line after a shell script exits gives + results consistent with the table above only from the + Bash or sh prompt. Running the + C-shell or tcsh + may give different values in some cases.
@@ -29397,10 +30243,10 @@ awk '{print $1 $5 $6}' $filename by the document author
A command expects the first three file - descriptors to be available. The first, fd - 0 (standard input, stdin), - is for reading. The other two (fd 1, - stdout and fd 2, + descriptors to be available. The first, fd + 0 (standard input, stdin), + is for reading. The other two (fd 1, + stdout and fd 2, stderr) are for writing. There is a stdin, stdout, @@ -29432,7 +30278,8 @@ awk '{print $1 $5 $6}' $filename linkend="ioredirref">Redirection means reassigning one of the file descriptors to another file (or a pipe, or anything permissible). File descriptors may be reassigned - locally (for a command, a command group, a subshell, a subshell, a while or if or case or for loop...), or globally, for the remainder of the shell (using exec). @@ -29556,13 +30403,13 @@ exit 0 - Help: Give usage message and exit. + Help: Give usage message and exit. - Version: Show program version and exit. + Version: Show program version and exit. @@ -29575,7 +30422,7 @@ exit 0 - All: show all + All: show all information or operate on all arguments. @@ -29583,40 +30430,41 @@ exit 0 - List: list files or arguments without + List: list files or arguments without taking other action. - Output filename + Output filename - Quiet: suppress stdout. + Quiet: suppress + stdout. - Recursive: Operate recursively (down + Recursive: Operate recursively (down directory tree). - Verbose: output additional information to + Verbose: output additional information to stdout or stderr. - Compress: apply compression (usually + Compress: apply compression (usually gzip). @@ -29631,7 +30479,7 @@ exit 0 In tar and gawk: - File: filename follows. + File: filename follows. @@ -29639,7 +30487,7 @@ exit 0 rm:
- Force: force overwrite of target file(s). + Force: force overwrite of target file(s). @@ -29861,7 +30709,7 @@ exit 0 /etc - Et cetera. Systemwide configuration + Et cetera. Systemwide configuration scripts. Of particular interest are the @@ -29886,7 +30734,7 @@ exit 0 /usr/man - The systemwide manpages. + The systemwide manpages. @@ -29912,7 +30760,7 @@ exit 0 /mnt - Mount. Directory for mounting + Mount. Directory for mounting hard drive partitions, such as /mnt/dos, and physical devices. In newer Linux distros, the /var - Variable (changeable) system + Variable (changeable) system files. This is a catchall scratchpad directory for data generated while a Linux/UNIX machine is running. @@ -29961,7 +30809,7 @@ exit 0 /boot - System boot directory. The kernel, + System boot directory. The kernel, module links, system map, and boot manager reside here. Altering files in this directory may result in an unbootable system. @@ -30201,7 +31049,7 @@ read -p "$(gettext -s "Enter the value: ")" var History Commands The Bash shell provides command-line tools for editing and - manipulating a user's command history. This + manipulating a user's command history. This is primarily a convenience, a means of saving keystrokes. Bash history commands: @@ -30801,7 +31649,7 @@ done < `tail -f /var/log/messages` Alter the script so that it accepts any ordinary ASCII text file as input for its initial generation. The - script will read the first $ROW*$COL + script will read the first $ROW*$COL characters, and set the occurrences of vowels as living cells. Hint: be sure to translate the spaces in the input file to underscore characters. @@ -30838,14 +31686,14 @@ done < `tail -f /var/log/messages` loops to while and until loops - Convert the for loops in to while - loops. Hint: store the data in an Convert the for loops in to while + loops. Hint: store the data in an array and step through the array elements. Having already done the heavy lifting, - now convert the loops in the example to until - loops. + now convert the loops in the example to until + loops.
@@ -30970,8 +31818,8 @@ done < `tail -f /var/log/messages` or a string. The function will return TRUE (0) if passed an integer, and FALSE (1) if passed a string. Hint: What does the following expression return - when $1 is not an - integer? + when $1 is not + an integer? expr $1 + 0
@@ -30993,7 +31841,7 @@ done < `tail -f /var/log/messages` Inactive accounts on a network waste disk space and may become a security risk. Write an administrative script - (to be invoked by root or the root or the cron daemon) that checks for and deletes user accounts that have not been accessed within the last 90 days. @@ -31067,14 +31915,14 @@ done < `tail -f /var/log/messages` Quadratic Equations Solve a quadratic equation of the form - Ax^2 + Bx + C = 0. Have a script take + Ax^2 + Bx + C = 0. Have a script take as arguments the coefficients, A, B, and C, and return the solutions to four decimal places. Hint: pipe the coefficients to bc, using the well-known formula, - x = ( -B +/- sqrt( B^2 - 4AC ) ) / 2A. + x = ( -B +/- sqrt( B^2 - 4AC ) ) / 2A.
@@ -31122,8 +31970,9 @@ done < `tail -f /var/log/messages` Parse /var/log/messages to produce a nicely formatted file of user logins and login - times. The script may need to run as root. (Hint: Search - for the string LOGIN.) + times. The script may need to run as + root. (Hint: Search for the string + LOGIN.)
@@ -31131,7 +31980,7 @@ done < `tail -f /var/log/messages` Pretty-Printing a Data File Certain database and spreadsheet packages use save-files - with comma-separated values + with comma-separated values (CSVs). Other applications often need to parse these files. Given a data file with comma-separated fields, @@ -31263,10 +32112,10 @@ Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612 processes and to keep track of how many child processes each parent spawns. If a process spawns more than five children, then the script sends an e-mail to the system administrator - (or root) with all relevant information, including the - time, PID of the parent, PIDs of the children, etc. The - script writes a report to a log file every ten minutes. - + (or root) with all relevant + information, including the time, PID of the parent, PIDs + of the children, etc. The script writes a report to a log + file every ten minutes.
@@ -31336,16 +32185,16 @@ Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612 Write a script that automates the process of creating - man pages. + man pages. Given a text file which contains information to be - formatted into a man page, the + formatted into a man page, the script will read the file, then invoke the appropriate groff commands to - output the corresponding man page + output the corresponding man page to stdout. The text file contains - blocks of information under the standard man - page headings, i.e., NAME, + blocks of information under the standard man + page headings, i.e., NAME, SYNOPSIS, DESCRIPTION, etc. @@ -31381,10 +32230,10 @@ Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612 Using as an inspiration, write a script that emulates a 64-bit shift register as - an array. Implement - functions to load the register, - shift left, shift - right, and rotate + an array. Implement + functions to load the register, + shift left, shift + right, and rotate it. Finally, write a function that interprets the register contents as eight 8-bit ASCII characters. @@ -31523,9 +32372,10 @@ Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612 a fractional multiple of PI. In the spirit of , write a - script that runs a Monte Carlo simulation of Buffon's - Needle. To simplify matters, set the needle length equal to - the distance between the cracks, n = d. + script that runs a Monte Carlo simulation of Buffon's + Needle. To simplify matters, set the needle length + equal to the distance between the cracks, n = + d. Hint: there are actually two critical variables: the distance from the center of the needle to the crack @@ -31546,7 +32396,7 @@ Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612 The Playfair Cipher encrypts text by substitution of digrams (2-letter groupings). It is traditional to use a 5 x 5 letter scrambled-alphabet - key square for the encryption and + key square for the encryption and decryption. @@ -31853,6 +32703,11 @@ fairly detailed rundown on the Playfair Cipher and its solution methods.15 May 2006 SPICEBERRY release: Bugfixes, some material added. + + + 18 Jun 2006 + WINTERBERRY release: Major reorganization. + @@ -31864,7 +32719,7 @@ fairly detailed rundown on the Playfair Cipher and its solution methods.Mirror Sites + url="http://thegrendel.150m.com/abs-guide-4.0.tar.bz2"> The latest update of this document, as an archived tarball including both the SGML source and rendered HTML, may diff --git a/LDP/guide/docbook/abs-guide/blank-rename.sh b/LDP/guide/docbook/abs-guide/blank-rename.sh index 1431fe63..e0743b77 100644 --- a/LDP/guide/docbook/abs-guide/blank-rename.sh +++ b/LDP/guide/docbook/abs-guide/blank-rename.sh @@ -12,7 +12,7 @@ do echo "$filename" | grep -q " " # Check whether filename if [ $? -eq $FOUND ] #+ contains space(s). then - fname=$filename # Strip off path. + fname=$filename # Yes, this filename needs work. n=`echo $fname | sed -e "s/ /_/g"` # Substitute underscore for blank. mv "$fname" "$n" # Do the actual renaming. let "number += 1" diff --git a/LDP/guide/docbook/abs-guide/broken-link.sh b/LDP/guide/docbook/abs-guide/broken-link.sh index eeee6851..b8228376 100644 --- a/LDP/guide/docbook/abs-guide/broken-link.sh +++ b/LDP/guide/docbook/abs-guide/broken-link.sh @@ -19,16 +19,16 @@ ############################################################## -#If no args are passed to the script set directorys to search -#to current directory. Otherwise set the directorys to search -#to the agrs passed. +#If no args are passed to the script set directories-to-search +#to current directory. Otherwise set the directories-to-search +#to the args passed. #################### [ $# -eq 0 ] && directorys=`pwd` || directorys=$@ #Setup the function linkchk to check the directory it is passed #for files that are links and don't exist, then print them quoted. #If one of the elements in the directory is a subdirectory then -#send that send that subdirectory to the linkcheck function. +#send that subdirectory to the linkcheck function. ########## linkchk () { for element in $1/*; do diff --git a/LDP/guide/docbook/abs-guide/days-between.sh b/LDP/guide/docbook/abs-guide/days-between.sh index a82f28d4..abd8d846 100644 --- a/LDP/guide/docbook/abs-guide/days-between.sh +++ b/LDP/guide/docbook/abs-guide/days-between.sh @@ -88,7 +88,7 @@ day_index () # Gauss' Formula: } -calculate_difference () # Difference between to day indices. +calculate_difference () # Difference between two day indices. { let "diff = $1 - $2" # Global variable. } diff --git a/LDP/guide/docbook/abs-guide/empty-array.sh b/LDP/guide/docbook/abs-guide/empty-array.sh index dc2b08ad..87d40263 100644 --- a/LDP/guide/docbook/abs-guide/empty-array.sh +++ b/LDP/guide/docbook/abs-guide/empty-array.sh @@ -2,14 +2,15 @@ # empty-array.sh # Thanks to Stephane Chazelas for the original example, -#+ and to Michael Zick for extending it. +#+ and to Michael Zick and Omair Eshkenazi for extending it. # An empty array is not the same as an array with empty elements. -array0=( first second third ) -array1=( '' ) # "array1" consists of one empty element. -array2=( ) # No elements . . . "array2" is empty. + array0=( first second third ) + array1=( '' ) # "array1" consists of one empty element. + array2=( ) # No elements . . . "array2" is empty. + array3=( ) # What about this array? echo ListArray() @@ -18,14 +19,17 @@ echo echo "Elements in array0: ${array0[@]}" echo "Elements in array1: ${array1[@]}" echo "Elements in array2: ${array2[@]}" +echo "Elements in array3: ${array3[@]}" echo echo "Length of first element in array0 = ${#array0}" echo "Length of first element in array1 = ${#array1}" echo "Length of first element in array2 = ${#array2}" +echo "Length of first element in array3 = ${#array3}" echo echo "Number of elements in array0 = ${#array0[*]}" # 3 echo "Number of elements in array1 = ${#array1[*]}" # 1 (Surprise!) echo "Number of elements in array2 = ${#array2[*]}" # 0 +echo "Number of elements in array3 = ${#array3[*]}" # 0 } # =================================================================== @@ -38,6 +42,7 @@ ListArray array0=( "${array0[@]}" "new1" ) array1=( "${array1[@]}" "new1" ) array2=( "${array2[@]}" "new1" ) +array3=( "${array3[@]}" "new1" ) ListArray @@ -45,6 +50,7 @@ ListArray array0[${#array0[*]}]="new2" array1[${#array1[*]}]="new2" array2[${#array2[*]}]="new2" +array3[${#array3[*]}]="new2" ListArray @@ -56,7 +62,7 @@ echo echo "Stack height for array2 = $height" # The 'pop' is: -unset array2[${#array2[@]}-1] # Arrays are zero-based, +unset array2[${#array2[@]}-1] # Arrays are zero-based, height=${#array2[@]} #+ which means first element has index 0. echo echo "POP" @@ -66,7 +72,7 @@ ListArray # List only 2nd and 3rd elements of array0. from=1 # Zero-based numbering. -to=2 # +to=2 array3=( ${array0[@]:1:2} ) echo echo "Elements in array3: ${array3[@]}" diff --git a/LDP/guide/docbook/abs-guide/erase.sh b/LDP/guide/docbook/abs-guide/erase.sh index a2e6b047..7447db54 100644 --- a/LDP/guide/docbook/abs-guide/erase.sh +++ b/LDP/guide/docbook/abs-guide/erase.sh @@ -12,6 +12,7 @@ echo -n "What is your name? " read name # Use # to erase last character typed. echo "Your name is $name." -# Warning: Even after the script exits, the new key value remains set. - exit 0 + +# Even after the script exits, the new key value remains set. +# Exercise: How would you reset the erase character to the default value? diff --git a/LDP/guide/docbook/abs-guide/ex11.sh b/LDP/guide/docbook/abs-guide/ex11.sh index 2019a2fc..587b1928 100644 --- a/LDP/guide/docbook/abs-guide/ex11.sh +++ b/LDP/guide/docbook/abs-guide/ex11.sh @@ -11,7 +11,8 @@ fi echo -if /usr/bin/test -z "$1" # Same result as "test" builtin". +if /usr/bin/test -z "$1" # Equivalent to "test" builtin. +# ^^^^^^^^^^^^^ # Specifying full pathname. then echo "No command-line arguments." else diff --git a/LDP/guide/docbook/abs-guide/ex24.sh b/LDP/guide/docbook/abs-guide/ex24.sh index aedd2627..32506dd9 100644 --- a/LDP/guide/docbook/abs-guide/ex24.sh +++ b/LDP/guide/docbook/abs-guide/ex24.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Faxing (must have 'fax' installed). +# Faxing (must have 'efax' package installed). EXPECTED_ARGS=2 E_BADARGS=65 @@ -14,24 +14,26 @@ fi if [ ! -f "$2" ] then - echo "File $2 is not a text file" + echo "File $2 is not a text file." + # File is not a regular file, or does not exist. exit $E_BADARGS fi -fax make $2 # Create fax formatted files from text files. +fax make $2 # Create fax formatted files from text files. -for file in $(ls $2.0*) # Concatenate the converted files. - # Uses wild card in variable list. +for file in $(ls $2.0*) # Concatenate the converted files. + # Uses wild card (filename "globbing") + #+ in variable list. do fil="$fil $file" done -efax -d /dev/ttyS3 -o1 -t "T$1" $fil # Do the work. +efax -d /dev/ttyS3 -o1 -t "T$1" $fil # Finally, do the work. -# As S.C. points out, the for-loop can be eliminated with -# efax -d /dev/ttyS3 -o1 -t "T$1" $2.0* -# but it's not quite as instructive [grin]. +# As S.C. points out, the for-loop can be eliminated with +# efax -d /dev/ttyS3 -o1 -t "T$1" $2.0* +#+ but it's not quite as instructive [grin]. exit 0 diff --git a/LDP/guide/docbook/abs-guide/ex41.sh b/LDP/guide/docbook/abs-guide/ex41.sh index 1cf22569..5fd1872d 100644 --- a/LDP/guide/docbook/abs-guide/ex41.sh +++ b/LDP/guide/docbook/abs-guide/ex41.sh @@ -12,7 +12,7 @@ LINES=5 ( date; uname -a ) >>logfile # Time and machine name echo --------------------------------------------------------------------- >>logfile -tail -$LINES /var/log/messages | xargs | fmt -s >>logfile +tail -$LINES /var/log/messages | xargs | fmt -s >>logfile echo >>logfile echo >>logfile diff --git a/LDP/guide/docbook/abs-guide/fc4upd.sh b/LDP/guide/docbook/abs-guide/fc4upd.sh index fea2bbd3..e8853229 100644 --- a/LDP/guide/docbook/abs-guide/fc4upd.sh +++ b/LDP/guide/docbook/abs-guide/fc4upd.sh @@ -63,7 +63,7 @@ EXCLUDE=( init () { # Let pipe command return possible rsync error, e.g., stalled network. - set -o pipefail + set -o pipefail # Newly introduced in Bash, version 3. TMP=${TMPDIR:-/tmp}/${0##*/}.$$ # Store refined download list. trap "{ diff --git a/LDP/guide/docbook/abs-guide/fifo.sh b/LDP/guide/docbook/abs-guide/fifo.sh index 729ef1b0..6838df3c 100644 --- a/LDP/guide/docbook/abs-guide/fifo.sh +++ b/LDP/guide/docbook/abs-guide/fifo.sh @@ -15,9 +15,9 @@ # ==> 'su xyz' runs commands as user "xyz". # ==> 'ssh' invokes secure shell (remote login client). - su xyz -c "ssh $THERE \"cat >/home/xyz/backup/${HERE}-daily.tar.gz\" < /pipe"& + su xyz -c "ssh $THERE \"cat > /home/xyz/backup/${HERE}-daily.tar.gz\" < /pipe"& cd / - tar -czf - bin boot dev etc home info lib man root sbin share usr var >/pipe + tar -czf - bin boot dev etc home info lib man root sbin share usr var > /pipe # ==> Uses named pipe, /pipe, to communicate between processes: # ==> 'tar/gzip' writes to /pipe and 'ssh' reads from /pipe. @@ -27,5 +27,8 @@ # ==>+ as opposed to an "anonymous pipe", with |? # ==> Will an anonymous pipe even work here? + # ==> Is it necessary to delete the pipe before exiting the script? + # ==> How could that be done? + exit 0 diff --git a/LDP/guide/docbook/abs-guide/ftpget.sh b/LDP/guide/docbook/abs-guide/ftpget.sh index 2775742b..c62b51cb 100644 --- a/LDP/guide/docbook/abs-guide/ftpget.sh +++ b/LDP/guide/docbook/abs-guide/ftpget.sh @@ -56,7 +56,8 @@ if [ $? != 0 ]; then exit $E_BADARGS fi shift -trap 'rm -f ${TMPFILE} ; exit' 0 1 2 3 15 +trap 'rm -f ${TMPFILE} ; exit' 0 1 2 3 15 +# ==> Signals: HUP INT (Ctl-C) QUIT TERM # ==> Delete tempfile in case of abnormal exit from script. echo "user anonymous ${USER-gnu}@${SITE} > ${TMPFILE}" # ==> Added quotes (recommended in complex echoes). diff --git a/LDP/guide/docbook/abs-guide/kill-byname.sh b/LDP/guide/docbook/abs-guide/kill-byname.sh index 6ad2d0a6..d0ccd452 100644 --- a/LDP/guide/docbook/abs-guide/kill-byname.sh +++ b/LDP/guide/docbook/abs-guide/kill-byname.sh @@ -33,3 +33,6 @@ ps ax | grep "$PROCESS_NAME" | awk '{print $1}' | xargs -i kill {} 2&>/dev/null # ----------------------------------------------------------- exit $? + +# The "killall" command has the same effect as this script, +#+ but using it is not quite as educational. diff --git a/LDP/guide/docbook/abs-guide/kill-process.sh b/LDP/guide/docbook/abs-guide/kill-process.sh index a463d885..87c57795 100644 --- a/LDP/guide/docbook/abs-guide/kill-process.sh +++ b/LDP/guide/docbook/abs-guide/kill-process.sh @@ -27,7 +27,9 @@ kill $t # May need 'kill -9' for stubborn process. # This entire script could be replaced by -# kill $(pidof -x process_name) +# kill $(pidof -x process_name) +# or +# killall process_name # but it would not be as instructive. exit 0 diff --git a/LDP/guide/docbook/abs-guide/random-between.sh b/LDP/guide/docbook/abs-guide/random-between.sh index bf399b55..61dbcfb3 100644 --- a/LDP/guide/docbook/abs-guide/random-between.sh +++ b/LDP/guide/docbook/abs-guide/random-between.sh @@ -93,6 +93,8 @@ randomBetween() { # --------------------------------------------------------------------- spread=$((max-min)) + # Omair Eshkenazi points out that this test is unnecessary, + #+ since max and min have already been switched around. [ ${spread} -lt 0 ] && spread=$((0-spread)) let spread+=divisibleBy randomBetweenAnswer=$(((RANDOM%spread)/divisibleBy*divisibleBy+min)) diff --git a/LDP/guide/docbook/abs-guide/read-novar.sh b/LDP/guide/docbook/abs-guide/read-novar.sh index 34f6c220..18505660 100644 --- a/LDP/guide/docbook/abs-guide/read-novar.sh +++ b/LDP/guide/docbook/abs-guide/read-novar.sh @@ -24,3 +24,7 @@ echo "\"var\" = "$var"" echo exit 0 + +# This example is similar to the "reply.sh" script. +# However, this one shows that $REPLY is available +#+ even after a 'read' to a variable in the conventional way. diff --git a/LDP/guide/docbook/abs-guide/wgetter2.bash b/LDP/guide/docbook/abs-guide/wgetter2.bash index 5dc023b8..65b7e30a 100644 --- a/LDP/guide/docbook/abs-guide/wgetter2.bash +++ b/LDP/guide/docbook/abs-guide/wgetter2.bash @@ -179,6 +179,7 @@ read Wopts # Read in the options to be passed to wget. Woptions=" $Wopts" +# ^ Why the leading space? # Assign to another variable. # Just for fun, or something . . .