From b20be133eca8c3870491d230d5867fec3d4af2c3 Mon Sep 17 00:00:00 2001 From: gferg <> Date: Tue, 3 May 2011 15:38:48 +0000 Subject: [PATCH] updated --- LDP/guide/docbook/abs-guide/BashExtraKeys.sh | 102 ++ LDP/guide/docbook/abs-guide/Change.log | 140 +- LDP/guide/docbook/abs-guide/INDEX00.sgml | 77 +- LDP/guide/docbook/abs-guide/README | 4 + LDP/guide/docbook/abs-guide/abs-guide.sgml | 1266 +++++++++++++---- LDP/guide/docbook/abs-guide/badread.sh | 8 + LDP/guide/docbook/abs-guide/base64.sh | 129 ++ .../docbook/abs-guide/bash-profile.snippet | 51 + LDP/guide/docbook/abs-guide/connect-stat.sh | 10 +- LDP/guide/docbook/abs-guide/escaped.sh | 26 +- LDP/guide/docbook/abs-guide/ex1.sh | 2 +- LDP/guide/docbook/abs-guide/ex1a.sh | 4 +- LDP/guide/docbook/abs-guide/ex2.sh | 4 +- .../docbook/abs-guide/fetch_address-2.sh | 18 +- LDP/guide/docbook/abs-guide/fetch_address.sh | 5 + LDP/guide/docbook/abs-guide/hanoi2.bash | 4 +- LDP/guide/docbook/abs-guide/here-commsub.sh | 25 + LDP/guide/docbook/abs-guide/ip-addresses.sh | 38 + .../docbook/abs-guide/lastpipe-option.sh | 20 + LDP/guide/docbook/abs-guide/max.sh | 2 +- LDP/guide/docbook/abs-guide/neg-array.sh | 36 + LDP/guide/docbook/abs-guide/neg-offset.sh | 21 + LDP/guide/docbook/abs-guide/numbers.sh | 6 +- LDP/guide/docbook/abs-guide/psub.bash | 20 + LDP/guide/docbook/abs-guide/random-between.sh | 5 +- LDP/guide/docbook/abs-guide/read-N.sh | 15 + LDP/guide/docbook/abs-guide/readpipe.sh | 6 +- LDP/guide/docbook/abs-guide/realname.sh | 2 +- .../docbook/abs-guide/resistor-inventory.sh | 1 + LDP/guide/docbook/abs-guide/test-cgi.sh | 9 +- 30 files changed, 1703 insertions(+), 353 deletions(-) create mode 100644 LDP/guide/docbook/abs-guide/BashExtraKeys.sh create mode 100644 LDP/guide/docbook/abs-guide/base64.sh create mode 100644 LDP/guide/docbook/abs-guide/bash-profile.snippet create mode 100644 LDP/guide/docbook/abs-guide/here-commsub.sh create mode 100644 LDP/guide/docbook/abs-guide/ip-addresses.sh create mode 100644 LDP/guide/docbook/abs-guide/lastpipe-option.sh create mode 100644 LDP/guide/docbook/abs-guide/neg-array.sh create mode 100644 LDP/guide/docbook/abs-guide/neg-offset.sh create mode 100644 LDP/guide/docbook/abs-guide/psub.bash create mode 100644 LDP/guide/docbook/abs-guide/read-N.sh diff --git a/LDP/guide/docbook/abs-guide/BashExtraKeys.sh b/LDP/guide/docbook/abs-guide/BashExtraKeys.sh new file mode 100644 index 00000000..fb6c7990 --- /dev/null +++ b/LDP/guide/docbook/abs-guide/BashExtraKeys.sh @@ -0,0 +1,102 @@ +#!/bin/bash +# Author: Sigurd Solaas, 20 Apr 2011 +# Used in ABS Guide with permission. +# Requires version 4.2+ of Bash. + +key="no value yet" +while true; do + clear + echo "Bash Extra Keys Demo. Keys to try:" + echo + echo "* Insert, Delete, Home, End, Page_Up and Page_Down" + echo "* The four arrow keys" + echo "* Tab, enter, escape, and space key" + echo "* The letter and number keys, etc." + echo + echo " d = show date/time" + echo " q = quit" + echo "================================" + echo + + # Convert the separate home-key to home-key_num_7: + if [ "$key" = $'\x1b\x4f\x48' ]; then + key=$'\x1b\x5b\x31\x7e' + # Quoted string-expansion construct. + fi + + # Convert the separate end-key to end-key_num_1. + if [ "$key" = $'\x1b\x4f\x46' ]; then + key=$'\x1b\x5b\x34\x7e' + fi + + case "$key" in + $'\x1b\x5b\x32\x7e') # Insert + echo Insert Key + ;; + $'\x1b\x5b\x33\x7e') # Delete + echo Delete Key + ;; + $'\x1b\x5b\x31\x7e') # Home_key_num_7 + echo Home Key + ;; + $'\x1b\x5b\x34\x7e') # End_key_num_1 + echo End Key + ;; + $'\x1b\x5b\x35\x7e') # Page_Up + echo Page_Up + ;; + $'\x1b\x5b\x36\x7e') # Page_Down + echo Page_Down + ;; + $'\x1b\x5b\x41') # Up_arrow + echo Up arrow + ;; + $'\x1b\x5b\x42') # Down_arrow + echo Down arrow + ;; + $'\x1b\x5b\x43') # Right_arrow + echo Right arrow + ;; + $'\x1b\x5b\x44') # Left_arrow + echo Left arrow + ;; + $'\x09') # Tab + echo Tab Key + ;; + $'\x0a') # Enter + echo Enter Key + ;; + $'\x1b') # Escape + echo Escape Key + ;; + $'\x20') # Space + echo Space Key + ;; + d) + date + ;; + q) + echo Time to quit... + echo + exit 0 + ;; + *) + echo You pressed: \'"$key"\' + ;; + esac + + echo + echo "================================" + + unset K1 K2 K3 + read -s -N1 -p "Press a key: " + K1="$REPLY" + read -s -N2 -t 0.001 + K2="$REPLY" + read -s -N1 -t 0.001 + K3="$REPLY" + key="$K1$K2$K3" + +done + +exit $? diff --git a/LDP/guide/docbook/abs-guide/Change.log b/LDP/guide/docbook/abs-guide/Change.log index 1c181426..5dbf791d 100644 --- a/LDP/guide/docbook/abs-guide/Change.log +++ b/LDP/guide/docbook/abs-guide/Change.log @@ -7,15 +7,149 @@ ================================================================== - Current version = 6.2 - Dated 03/17/10 + Current version = 6.3 + Dated 04/30/12 http://bash.webofcrafts.net/abs-guide-latest.tar.bz2 http://bash.webofcrafts.net/abs-guide.pdf -------------------------------------------------------------------- - News: Version 6.2 released! + News: Version 6.3 released! ==================================================================== +Version 6.3, Swozzleberry* release +30 April, 2011 + +1) Added brief coverage of Bash 4.1/4.2 releases. + Read -N. + Negative array indices. + Negative parameter in string extraction. + Bash now recognizes \u unicode escape. + There is a new "lastpipe" shell option. + etc. + +2) In "Shell Programming!" chapter, + Fixed the URL on the Christensen quote. + (Thanks, Ilario Fav.) + +3) In "Special Characters" chapter, + Revised "?:" trinary-construct entry. + Added $' ... ' entry. + Added definition of ASCII. + +4) In the "Tests" chapter, + At "-p" entry, added Carl Anderson's example. + +5) In "Introduction to Variables and Parameters" chapter: + In "Variable Substitution" section: + Corrected comment concerning when variables appear "naked." + Removed comment about non-portable behavior of uninitialize + variables in arithmetic expressions. + (Thank you, Jeffery Haemer.) + Added footnote that $0 does not always return the script name. + (Thank you, Gregg Leichtman!) + +6) In "Internal Commands and Builtins" chapter, + At "let" entry, + added caution about misleading exit status returned in certain + situations. (Thank you, Evgeniy Ivanov.) + In "Job controls" subsection, + added footnote that "wait" can only take PIDs of child processes + as arguments. + (Thank you, Simon Haller.) + +7) In "I/O Redirection" chapter: + Fixed commentary on "ls -yz 2>&1 >> command.log" example. + (Thank you, Teika Kazura.) + +8) In "max.sh" example script, fixed comment. + (Thank you, Robert Bruntz.) + +9) In the "Bash, versions 2,3, and 4" chapter, + removed the "{X..d..2}" example. + (Thank you, Jeffrey Haemer, for the pointer.) + +10) In "Bash, versions 2, 3, and 4" chapter, + In the Version 3.1 section, + At the "+=" entry, added Jeffrey Haemer's $PATH append example. + +11) In "Local Variables" section of "Functions" chapter: + Added note about return value of setting local variable. + (Thank you, Evegniy Ivanov.) + +12) In "Complex Commands" section of "External Commands" Chapter: + At "xargs" entry: + Added tip about using the -P option to run processes in parallel. + (Thank you, Roberto Polli.) + +13) In "Here Documents" chapter: + Added footnote about using <<- to suppress tabs allowing closing limit + string to deviate from the first column on a line. + (Thank you, Dennis Benzinger.) + +14) In the "Miscellany" chapter: + Fixed the URL on Moshe Jacobson's utility (changed it to point to + the "ansi-color" script). Then, decided to rehost Jacobson's original + source code on webofcrafts.net. + (Thank you, qun-ying, for pointing out the broken URL.) + +15) In the "Variables Revisited" chapter: + In "Parameter Substitution" section: + Revised the "${parameter:?err_msg}" entry, per Kevin LeBlanc + (thanks!). + +16) In "Process Substitution" chapter: + Added "psub.bash" example of redirecting output of process + substitution into a loop. + (Thanks, Diego Molina!) + +17) Reference cards: + Revisions, per Kevin LeBlanc (thanks!). + +18) Added a snippet from Andrzej Szelachowski's ~/.bash_profile file + to the ".bashrc" Appendix. + (Thanks!) + +19) In "/dev" section of "/dev and /proc" chapter: + Expanded Mark's command-line time-fetch example into a short script. + +20) In "Network" subsection of "System and Administrative Commands," + Added "iptables" entry. + Moved "nmap" and "netstat" entries here. + +21) Added "Network Programming" chapter. + Moved "test-cgi.sh" script here from TODO section. + +22) In "Escaping" section of "Quoting" Chapter: + Broke out $' ... ' string-expansion as a separate topic. + (This was a long-overdue fixup.) + +23) New scripts: + read-N.sh + here-commsub.sh + neg-array.sh + neg-offset.sh + base64.sh + ip-addresses.sh + lastpipe-option.sh + BashExtraKeys.sh (with thanks to Sigurd Solaas). + Long in-line example at "Unicode" entry, + with tie-in to $' ... ' string-expansion. + +24) In "Writing Scripts" section of "Exercises" appendix: + Added "Unicode Table" exercise to Intermediate section. + +25) Fixups on various typos. + +26) Fixups on scripts. + + * Swozzleberry? There really is such a thing? + It's a variant spelling of "swazzle," + a sort of kazoo-like noisemaker used by puppeteers. + Now, imagine a gourd-like berry that can be used + to make funny sounds. . . . + + + Version 6.2, Rowanberry release 17 March, 2010 diff --git a/LDP/guide/docbook/abs-guide/INDEX00.sgml b/LDP/guide/docbook/abs-guide/INDEX00.sgml index 3e25d532..b8cd36dc 100644 --- a/LDP/guide/docbook/abs-guide/INDEX00.sgml +++ b/LDP/guide/docbook/abs-guide/INDEX00.sgml @@ -535,6 +535,10 @@ + $' ... ' + String expansion, + using escaped characters. + \ Escape the character following @@ -881,7 +885,14 @@ Arrow keys, detecting - ASCII table + ASCII + + Definition + + Script to generate ASCII table + + awk field-oriented text @@ -930,8 +941,11 @@ Version 2 Version 3 - - Version 4 + + Version 4 + Version 4.1 + Version 4.2 + @@ -956,7 +970,13 @@ Bibliography Bison utility - Bitwise operators + + Bitwise operators + + Example script + + + Block devices @@ -1339,8 +1359,17 @@ comparison test Eratosthenes, Sieve of, algorithm for generating prime numbers + Escaped characters, - special meanings of + special meanings of + + Within $' ... ' + string expansion + Used with + Unicode characters + + + /etc/fstab (filesystem mount) file @@ -1390,6 +1419,9 @@ Table, Exit codes with special meanings + + Anomalous + Out of range Pipe exit status @@ -1800,6 +1832,17 @@ + + iptables, + packet filtering and firewall utility + + Usage + example + Example + script + + + Iteration * * * @@ -1834,6 +1877,9 @@ * * * + lastpipe shell + option + -le , less-than or equal integer comparison test @@ -2047,6 +2093,7 @@ linkend="ifthen">test netstat, Network statistics + Network programming nl, a filter to number lines of text Noclobber, @@ -2156,7 +2203,13 @@ $PATH, the path (location of system - binaries) + binaries) + + Appending directories to $PATH + using the += + operator. + + Perl, programming language Combined in the @@ -2236,6 +2289,10 @@ using Execute permission lacking for commands within a script + + Exit status, + anomalous + Export problem, child process @@ -3156,6 +3213,9 @@ the return value of a function, using echo + CGI + programming, using scripts for + Comment blocks Using anonymous @@ -3192,6 +3252,9 @@ Passing an array to a function + $PATH, + appending to, using the + += operator. Prepending lines at head of a file @@ -3297,6 +3360,8 @@ to remove an alias uname, output system information + Unicode, encoding standard + for representing letters and symbols Uninitialized variables uniq, filter to remove duplicate lines from a sorted file diff --git a/LDP/guide/docbook/abs-guide/README b/LDP/guide/docbook/abs-guide/README index 66bb1077..68cd06f5 100644 --- a/LDP/guide/docbook/abs-guide/README +++ b/LDP/guide/docbook/abs-guide/README @@ -114,11 +114,15 @@ progress-bar.sh line 30 nim.sh line 27 + paragraph-spac3.sh line 6 sw.sh line 5 (comment) +here-commsub.sh + line 5 + UseGetOpt.sh: line 4 (comment) UseGetOpt-2.sh: line 11 (comment) diff --git a/LDP/guide/docbook/abs-guide/abs-guide.sgml b/LDP/guide/docbook/abs-guide/abs-guide.sgml index fcfd22ae..827060fe 100644 --- a/LDP/guide/docbook/abs-guide/abs-guide.sgml +++ b/LDP/guide/docbook/abs-guide/abs-guide.sgml @@ -359,6 +359,7 @@ + @@ -368,13 +369,22 @@ + + + + + + + + + ]> @@ -394,21 +404,14 @@ - 6.2 - 17 March 2010 + 6.3. + 30 Apr 2011 978-1-4357-5219-1 - - 6.0 - 23 Mar 2009 - mc - 'THIMBLEBERRY' release: Major Update. - - 6.1 30 Sep 2009 @@ -423,6 +426,13 @@ 'ROWANBERRY' release + + 6.3 + 27 Apr 2011 + mc + 'SWOZZLEBERRY' release + + @@ -652,7 +662,7 @@ 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 Usenet + url="http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/">Usenet post by Tom Christiansen.) What follows is a tutorial on shell scripting. It relies @@ -706,7 +716,7 @@ it is invoked. - <firstterm>cleanup</firstterm>: A script to clean up the log + <title><firstterm>cleanup</firstterm>: A script to clean up log files in /var/log &ex1; @@ -815,7 +825,7 @@ echo $a # Value of $a stays at 1. #!/usr/bin/perl #!/usr/bin/tcl #!/bin/sed -f -#!/usr/awk -f +#!/bin/awk -f Each of the above script header lines calls a different command interpreter, be it /bin/sh, the default shell @@ -1747,10 +1757,11 @@ fi In a double-parentheses construct, the ? can serve as an element of a C-style - trinary operator, - ?:. + trinary operator. - (( var0 = var1<98?9:21 )) + condition?result-if-true:result-if-false + + (( var0 = var1<98?9:21 )) # ^ ^ # if [ "$var1" -lt 98 ] @@ -1876,6 +1887,48 @@ echo $var2 # 23skidoo + $' ... ' + + $' ... ' + + + special character + $ + + + string expansion + + + string expansion + + + + <link linkend="strq">Quoted string + expansion</link> + This construct expands single or multiple + escaped octal or hex values into ASCII + + + + American + Standard + Code + for + Information + Interchange. + This is a system for encoding text characters + (alphabetic, numeric, and a limited set of symbols) + as numbers that can be stored and manipulated by + computers. Many of the ASCII characters are + represented on a standard keyboard. + + or Unicode + characters. + + + + + $* $@ @@ -2075,7 +2128,12 @@ cp file22.{txt,backup} # Echoes characters between a and z. echo {0..3} # 0 1 2 3 -# Echoes characters between 0 and 3. +# Echoes characters between 0 and 3. + + +base64_charset=( {A..Z} {a..z} {0..9} + / = ) +# Initializing an array, using extended brace expansion. +# From vladz's "base64.sh" example script. @@ -2181,7 +2239,7 @@ echo "First line is $firstline; second line is $secondline" # Won't work. # ^^ ^^ # From "ex42.sh" (copydir.sh) example. - anchor id="semicolonesc"> + @@ -3668,17 +3726,19 @@ echo <Ctl-V><Ctl-J> - The only time a variable appears naked + The only times a variable appears naked -- without the $ prefix -- is when 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), - in a read statement, - and at the head of a loop (for var2 in 1 2 - 3). + in an arithmetic expression within double parentheses + (( ... )), or in the special case of a variable + representing a signal + (see ). Assignment may be with an + = (as in var1=27), + in a read statement, + and at the head of a loop (for var2 in 1 + 2 3). Enclosing a referenced value in @@ -3729,9 +3789,7 @@ echo "$uninitialized" # 5 # Conclusion: # An uninitialized variable has no value, -#+ however it acts as if it were 0 in an arithmetic operation. -# This is undocumented (and probably non-portable) behavior, -#+ and should not be used in a script. +#+ however it evaluates as 0 in an arithmetic operation. See also . @@ -3791,7 +3849,7 @@ echo "$uninitialized" # 5 Variable assignment using the $(...) mechanism (a newer method than backquotes). This is - actually a form of command + likewise a form of command substitution. # From /etc/rc.d/rc.local @@ -3997,9 +4055,16 @@ lastarg=${!args} Some scripts can perform different operations, depending on which name they are invoked with. For this to work, the script needs to check $0, - the name it was invoked by. There must also exist symbolic - links to all the alternate names of the script. See . + the name it was invoked by. + + If the the script is sourced or symlinked, then + this will not work. It is safer to check $BASH_Source. + + There must also exist symbolic links to all the alternate + names of the script. See . If a script expects a command-line parameter @@ -4519,18 +4584,31 @@ echo 'Why can'\''t I write '"'"'s between single quotes' octal ASCII translates to the - octal ASCII equivalent of 0nn, - where nn is a string of - digits + octal ASCII + equivalent of 0nn, where + nn is a string of digits + + + + The $' ... ' + quoted string-expansion + construct is a mechanism that uses escaped octal or hex values + to assign ASCII characters to variables, e.g., + quote=$'\042'. + Escaped Characters &escaped; - See for another example of the - $' ... ' string-expansion - construct. + A more elaborate example: + + Detecting key-presses + &bashek; + + + See also . @@ -5501,8 +5579,20 @@ fi -p - file is a pipe + + file is a pipe + function show_input_type() +{ + [ -p /dev/fd/0 ] && echo PIPE || echo STDIN +} + +show_input_type "Input" # STDIN +echo "Input" | show_input_type # PIPE + +# This example courtesy of Carl Anderson. + + -h file is a symbolic @@ -5817,7 +5907,9 @@ fi < - is less than, in ASCII alphabetical order + is less than, in ASCII alphabetical + order if [[ "$a" < "$b" ]] if [ "$a" \< "$b" ] Note that the < needs to be @@ -6259,11 +6351,22 @@ echo "z = $z" # z = 125 plus-equal - plus-equal (increment - variable by a constant) + + plus-equal (increment variable + by a constant) + + In a different context, += can + serve as a string concatenation + operator. This can be useful for modifying environmental + variables. + + + let "var += 5" results in var being incremented by 5. + @@ -6401,7 +6504,10 @@ echo "b = $b" # b=1 from ports or sockets. Bit flipping is more relevant to compiled languages, such as C and C++, which provide direct access to system - hardware. + hardware. However, see vladz's + ingenious use of bitwise operators in his + base64.sh () + script. <anchor id="bitwsops1">bitwise operators @@ -8780,6 +8886,14 @@ bar # Prints nothing. $RANDOM $RANDOM: generate random integer + + + Anyone who attempts to generate random numbers by + deterministic means is, of course, living in a state of + sin. + --John von Neumann + + $RANDOM is an internal Bash function (not a constant) that @@ -9745,7 +9859,12 @@ echo "a = $a" # a = xyz ${parameter?err_msg} ${parameter:?err_msg} - If parameter set, use it, else print err_msg. + If parameter set, use it, else print + err_msg and abort + the script with an exit status of + 1. + Both forms nearly equivalent. The : makes a difference only when parameter has been declared and is null, as above. @@ -11598,6 +11717,7 @@ let "z += 3" # Quotes permit the use of spaces in variable assignment. install ip ipcalc + iptables iwconfig jobs join @@ -12480,6 +12600,36 @@ while read f; do &ex46; + + + + The let command can, + in certain contexts, return an anomalous exit status. + # Evgeniy Ivanov points out: + +var=0 +echo $? # 0 + # As expected. + +let var++ +echo $? # 1 + # The command was successful, so why isn't $?=0 ??? + # Anomaly! + +let var++ +echo $? # 0 + # As expected. + + +# Likewise . . . + +let var=0 +echo $? # 1 + # The command was successful, so why isn't $?=0 ??? + # Anomaly! + + @@ -12760,6 +12910,11 @@ eval eval echo $a # d + + A variable to be exported may require special + treatment. See . + + @@ -13116,6 +13271,7 @@ shift $(($OPTIND - 1)) shopt -s cdspell # Allows minor misspelling of directory names with 'cd' +# Option -s sets, -u unsets. cd /hpme # Oops! Mistyped '/home'. pwd # /home @@ -13540,8 +13696,12 @@ done Optionally, wait can take a job identifier as an argument, for example, wait%1 or wait - $PPID. See the job - id table. + $PPID. + + This only applies to child + processes, of course. + + See the job id table. @@ -14234,8 +14394,8 @@ chmod u+s filename # (This does not apply to shell scripts.) chmod 644 filename -# Makes "filename" readable/writable to owner, readable to others -# (octal mode). +# Makes "filename" readable/writable to owner, readable to others +#+ (octal mode). chmod 444 filename # Makes "filename" read-only for all. @@ -14250,7 +14410,7 @@ chmod 444 filename #+ however also sets the "sticky bit". # This means that only the owner of the directory, #+ owner of the file, and, of course, root -#+ can delete any particular file in that directory. +#+ can delete any particular file in that directory. chmod 111 directory-name # Gives everyone execute-only permission in a directory. @@ -14715,6 +14875,25 @@ done #+ script in "/dev and /proc" chapter. + + + The option to + xargs permits running + processes in parallel. This speeds up execution + in a machine with a multicore CPU. + #!/bin/bash + +ls *gif | xargs -t -n1 -P2 gif2png +# Converts all the gif images in current directory to png. + +# Options: +# ======= +# -t Print command to stderr. +# -n1 At most 1 argument per command line. +# -P2 Run up to 2 processes simultaneously. + +# Thank you, Roberto Polli, for the inspiration. + @@ -16932,11 +17111,12 @@ function write_utf8_string { The pax - portable archive - exchange toolkit - facilitates periodic file backups and is designed - to be cross-compatible between various flavors of UNIX. - It was ported from BSD to Linux. + portable archive + exchange toolkit facilitates periodic + file backups and is designed to be cross-compatible + between various flavors of UNIX. It was designed + to replace tar and cpio. pax -wf daily_backup.pax ~/linux-server/files @@ -17081,10 +17261,11 @@ pax -rf daily_backup.pax ~/bsd-server/files Yet another compression (squeeze) utility, a filter that works only on sorted - ASCII word lists. It uses the standard invocation - syntax for a filter, sq < input-file > - output-file. Fast, but not nearly as efficient - as gzip. The corresponding + ASCII word lists. It + uses the standard invocation syntax for a filter, + sq < input-file > output-file. + Fast, but not nearly as efficient as gzip. The corresponding uncompression filter is unsq, invoked like sq. @@ -18010,10 +18191,12 @@ gzip -cd patchXX.gz | patch -p0 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. This is especially useful where MIME - (multimedia) encoding is not available. + compressed files, etc.) into ASCII characters, making + them suitable for transmission in the body of an + e-mail message or in a newsgroup posting. This is + especially useful where MIME (multimedia) encoding + is not available. @@ -18591,6 +18774,7 @@ echo "tempfile name = $tempfile" an exit status of 0. This can be tested for in a script. + HNAME=nastyspammer.com # HNAME=$HOST # Debug: test for localhost. @@ -19905,12 +20089,13 @@ eval set -- "$args" Prints arguments as a large vertical banner to - stdout, using an ASCII character - (default '#'). This may be redirected to a printer for + stdout, using an ASCII character (default + '#'). This may be redirected to a printer for hardcopy. - + Note that banner has been - dropped from many Linux distros. + dropped from many Linux distros. @@ -21535,6 +21720,9 @@ setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ< + See for an effective use + of lsof. + @@ -21603,36 +21791,6 @@ getenv("DF_BLOCK_SIZE") = NULL - - nmap - - nmap - - - command - port scan - - - Network mapper - and port scanner. This command scans a server to - locate open ports and the services associated with those - ports. It can also report information about packet filters and - firewalls. This is an important security tool for locking down - a network against hacking attempts. - #!/bin/bash - -SERVER=$HOST # localhost.localdomain (127.0.0.1). -PORT_NUMBER=25 # SMTP port. - -nmap $SERVER | grep -w "$PORT_NUMBER" # Is that particular port open? -# grep -w matches whole words only, -#+ so this wouldn't match port 1025, for example. - -exit 0 - -# 25/tcp open smtp - - nc @@ -21924,43 +22082,6 @@ File access rights: -rw-rw-r-- - - netstat - - netstat - - - command - netstat - - - - Show current network statistics and information, - such as routing tables and active connections. This utility - accesses information in /proc/net - (). See . - netstat -r is equivalent to route. - - bash$ netstat -Active Internet connections (w/o servers) - Proto Recv-Q Send-Q Local Address Foreign Address State - Active UNIX domain sockets (w/o servers) - Proto RefCnt Flags Type State I-Node Path - unix 11 [ ] DGRAM 906 /dev/log - unix 3 [ ] STREAM CONNECTED 4514 /tmp/.X11-unix/X0 - unix 3 [ ] STREAM CONNECTED 4513 - . . . - - A netstat -lptu shows sockets that are listening - to ports, and the associated processes. This can be useful - for determining whether a computer has been hacked or - compromised. - - - uptime @@ -21984,8 +22105,8 @@ File access rights: -rw-rw-r-- A load average of 1 or less indicates that the system handles processes immediately. A load average greater than 1 means that processes are being queued. When - the load average gets above 3, then system performance is - significantly degraded. + the load average gets above 3 (on a single-core processor), + then system performance is significantly degraded. @@ -22673,13 +22794,17 @@ Average: all 6.33 1.70 14.71 0.00 77.26/etc/init.d and /etc/rc.d use this command to start services at bootup. - + + + + root# /sbin/service iptables stop Flushing firewall rules: [ OK ] Setting chains to policy ACCEPT: filter [ OK ] Unloading iptables modules: [ OK ] + @@ -22689,6 +22814,37 @@ Average: all 6.33 1.70 14.71 0.00 77.26 <anchor id="networksys1">Network + + nmap + + nmap + + + command + port scan + + + Network mapper + and port scanner. This command scans a server to + locate open ports and the services associated with those + ports. It can also report information about packet filters and + firewalls. This is an important security tool for locking down + a network against hacking attempts. + #!/bin/bash + +SERVER=$HOST # localhost.localdomain (127.0.0.1). +PORT_NUMBER=25 # SMTP port. + +nmap $SERVER | grep -w "$PORT_NUMBER" # Is that particular port open? +# grep -w matches whole words only, +#+ so this wouldn't match port 1025, for example. + +exit 0 + +# 25/tcp open smtp + + + ifconfig @@ -22749,6 +22905,44 @@ echo `/sbin/ifconfig | grep ^[a-z] | awk '{print $1}'` + + netstat + + netstat + + + command + netstat + + + + Show current network statistics and information, + such as routing tables and active connections. This utility + accesses information in /proc/net + (). See . + netstat -r is equivalent to route. + + bash$ netstat +Active Internet connections (w/o servers) + Proto Recv-Q Send-Q Local Address Foreign Address State + Active UNIX domain sockets (w/o servers) + Proto RefCnt Flags Type State I-Node Path + unix 11 [ ] DGRAM 906 /dev/log + unix 3 [ ] STREAM CONNECTED 4514 /tmp/.X11-unix/X0 + unix 3 [ ] STREAM CONNECTED 4513 + . . . + + A netstat -lptu shows sockets that are listening + to ports, and the associated processes. This can be useful + for determining whether a computer has been hacked or + compromised. + + + + iwconfig @@ -22798,7 +22992,7 @@ echo `/sbin/ifconfig | grep ^[a-z] | awk '{print $1}'` Or, in a script: - + &ipscript; @@ -22830,6 +23024,40 @@ echo `/sbin/ifconfig | grep ^[a-z] | awk '{print $1}'` + + + iptables + + iptables + + + command + firewall + + + + + The iptables command set is + a packet filtering tool used mainly for such security + purposes as setting up network firewalls. This + is a complex tool, and a detailed explanation of + its use is beyond the scope of this document. Oskar + Andreasson's tutorial is a reasonable starting + point. + + See also shutting down + iptables and . + + + + + + + + chkconfig @@ -24783,9 +25011,10 @@ echo a111b | gawk '/a1+b/' [:graph:] (graphic printable - characters). Matches characters in the range of ASCII 33 - - 126. This is the same as [:print:], - below, but excluding the space character. + characters). Matches characters in the range of ASCII 33 - 126. This is + the same as [:print:], below, + but excluding the space character. @@ -25083,6 +25312,8 @@ then # POSIX char class COMMAND <<InputComesFromHERE ... +... +... InputComesFromHERE @@ -25102,8 +25333,7 @@ command #2 The here document alternative looks like this: - #!/bin/bash -interactive-program <<LimitString + interactive-program <<LimitString command #1 command #2 ... @@ -25345,7 +25575,14 @@ fi be no leading whitespace. Trailing whitespace after the limit string likewise causes unexpected behavior. The whitespace prevents the limit string from being - recognized. + recognized. + + Except, as Dennis Benzinger points out, + if using + <<- to suppress + tabs. + + @@ -25682,7 +25919,9 @@ command1 | command2 | command3 > output-file # 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. +# Outputs an error message, but does not write to file. +# More precisely, the command output (in this case, null) +#+ writes to the file, but the error message goes only to stdout. # If redirecting both stdout and stderr, #+ the order of the commands makes a difference. @@ -26420,6 +26659,14 @@ exec 3>&- &wrps; + This is a similar example. + + + Redirecting the output of <firstterm>process + substitution</firstterm> into a loop. + &psubp; + + A reader sent in the following interesting example of process substitution. @@ -27091,11 +27338,59 @@ echo "global_var = $global_var" # global_var = 37 + + + As Evgeniy Ivanov points out, when declaring and + setting a local variable in a single command, apparently the + order of operations is to first set the variable, + and only afterwards restrict it to local scope. + This is reflected in the return value. + + #!/bin/bash + +echo "==OUTSIDE Function (global)==" +t=$(exit 1) +echo $? # 1 + # As expected. +echo + +function0 () +{ + +echo "==INSIDE Function==" +echo "Global" +t0=$(exit 1) +echo $? # 1 + # As expected. + +echo +echo "Local declared & assigned in same command." +local t1=$(exit 1) +echo $? # 0 + # Unexpected! +# Apparently, the variable assignment takes place before +#+ the local declaration. +#+ The return value is for the latter. + +echo +echo "Local declared, then assigned (separate commands)." +local t2 +t2=$(exit 1) +echo $? # 1 + # As expected. + +} + +function0 + + + Local variables and recursion. @@ -27492,6 +27787,14 @@ false && ( true || echo false ) # (nothing echoed) is the array=( element1 element2 ... elementN ) notation. + +base64_charset=( {A..Z} {a..z} {0..9} + / = ) + # Using extended brace expansion + #+ to initialize the elements of the array. + # Excerpted from vladz's "base64.sh" script + #+ in the "Contributed Scripts" appendix. + + Bash permits array operations on variables, even if @@ -28087,7 +28390,7 @@ echo $? # 1 locations on the Internet. - The following examples assume an active Internet + The following examples assume an active Internet connection. Getting the time from nist.gov: @@ -28095,9 +28398,20 @@ echo $? # 1 53082 04-03-18 04:26:54 68 0 0 502.3 UTC(NIST) * - [Mark contributed the above example.] + [Mark contributed this example.] - Downloading a URL: + Generalizing the above into a script: + #!/bin/bash + +URL="time.nist.gov/13" + +Time=$(cat </dev/tcp/"$URL") +UTC=$(echo "$Time" | awk '{print$3}') # Third field is UTC (GMT) time. +# Exercise: modify this for different time zones. + +echo "UTC Time = "$UTC"" + + Downloading a URL: bash$ exec 5<>/dev/tcp/www.net.cn/80 bash$ echo -e "GET / HTTP/1.0\n" >&5 bash$ cat <&5 @@ -28350,6 +28664,65 @@ fi + + Network Programming + + + The Net's a cross between an elephant and a white + elephant sale: it never forgets, and it's always crap. + --Nemo + + + A Linux system has quite a number of tools for accessing, + manipulating, and troubleshooting network connections. We can + incorporate some of these tools into scripts -- scripts that + expand our knowledge of networking, useful scripts that can + facilitate the administration of a network. + + Here is a simple CGI + script that demonstrates connecting to a remote server. + + + Print the server environment + &testcgi; + + + For security purposes, it may be helpful to identify the IP + addresses a computer is accessing. + + + + + IP addresses + &ipaddresses; + + + More examples of network programming: + + Getting the time from + nist.gov + Downloading a + URL + A GRE + tunnel + Checking + if an Internet server is up + + + + + + + + See also the networking commands + in the System and + Administrative Commands chapter and the communications commands in + the External Filters, Programs and + Commands chapter. + + + @@ -28437,12 +28810,12 @@ ln -s /dev/null ~/.netscape/cookies Like /dev/null, /dev/zero is a pseudo-device file, but it actually produces a stream of nulls - (binary zeros, not the ASCII - kind). Output written to /dev/zero - disappears, and it is fairly difficult to actually read - the nulls emitted there, though it can be done with od or a hex editor. The chief use of + (binary zeros, not the ASCII kind). Output written + to /dev/zero disappears, and it is + fairly difficult to actually read the nulls emitted there, + though it can be done with od + or a hex editor. The chief use of /dev/zero is creating an initialized dummy file of predetermined length intended as a temporary swap file. @@ -28807,8 +29180,10 @@ trap 'echo "Control-C disabled."' 2 + $BASH_SOURCE - Same as $0. + This is the name of the script, usually the same as + $0. @@ -29212,11 +29587,23 @@ if [ $a -le 5] # if [ $a -le 5 ] is correct. uninitialized variable has a value of null, not zero. + #!/bin/bash echo "uninitialized_var = $uninitialized_var" -# uninitialized_var = +# uninitialized_var = + +# However . . . +# if $BASH_VERSION ≥ 4.2; then + +if [[ ! -v uninitialized_var ]] +then + uninitialized_var=0 # Initialize it to zero! +fi + + + @@ -29376,6 +29763,15 @@ fi + + + In certain contexts, a misleading exit status + may be returned. This may occur when setting a local variable within a + function or when assigning + an arithmetic value to a variable. + @@ -29520,7 +29916,7 @@ do echo "Consider moving the file to archives." foundone=true # ------------------------------------ - echo "Subshell level = $BASH_SUBSHELL" + echo "Subshell level = $BASH_SUBSHELL" # Subshell level = 1 # Yes, we're inside a subshell. # ------------------------------------ @@ -29945,6 +30341,7 @@ exit 0 prompt.) if [ -z $PS1 ] # no prompt? +### if [ -v PS1 ] # On Bash 4.2+ ... then # non-interactive ... @@ -30174,7 +30571,7 @@ test "$city" \< Paris && echo "Yes, Paris is greater than $city" - A script calling itself (recursion) + Recursion: a script calling itself @@ -30392,12 +30789,12 @@ test "$city" \< Paris && echo "Yes, Paris is greater than $city" are probably inappropriate in a commercial setting, i.e., your supervisor might disapprove. - Moshe Jacobson's color utility - (http://runslinux.net/projects.html#color) - considerably simplifies using ANSI escape sequences. It - substitutes a clean and logical syntax for the clumsy constructs - just discussed. + Alister's + ansi-color utility (based on Moshe + Jacobson's color utility considerably simplifies using + ANSI escape sequences. It substitutes a clean and logical + syntax for the clumsy constructs just discussed. Henry/teikedvl has likewise created a utility (http://scriptechocolor.sourceforge.net/) to simplify creation of colorized scripts. @@ -31675,6 +32072,26 @@ let a+=Hello # Doesn't "add" anything to a. echo $a # 6 + Jeffrey Haemer points out + that this concatenation operator can be quite + useful. In this instance, we append a directory to the + $PATH. + + + + +bash$ echo $PATH +/usr/bin:/bin:/usr/local/bin:/usr/X11R6/bin/:/usr/games + + +bash$ PATH+=/opt/bin + +bash$ echo $PATH +/usr/bin:/bin:/usr/local/bin:/usr/X11R6/bin/:/usr/games:/opt/bin + + + + @@ -31751,7 +32168,14 @@ echo $a # 6 - Associative arrays. + Associative arrays. + To be more specific, Bash 4+ has + limited support for associative + arrays. It's a bare-bones implementation, + and it lacks the much of the functionality of such + arrays in other programming languages. + + An associative array can be thought of as a set of two linked arrays -- one holding @@ -32006,10 +32430,7 @@ echo {60..40..-2} # But, what about letters and symbols? echo {X..d} # X Y Z [ ] ^ _ ` a b c d -echo {X..d..2} -# X Z ^ ` b d -# It seems to work for upper/lowercase letters, -#+ but the increment is a bit inconsistent on symbols. +# Does not echo the \ which escapes a space. Zero-padding, specified in the first term within braces, prefixes each term in the output @@ -32035,8 +32456,9 @@ echo {X..d..2} zero-index. (This corrects an inconsistency in the treatment of positional parameters.) - #!/bin/bash4 -# show-params.bash4 + #!/bin/bash +# show-params.bash +# Requires version 4+ of Bash. # Invoke this scripts with at least one positional parameter. @@ -32155,6 +32577,196 @@ bad_command arg1 arg2 + + Bash, version 4.1 + + Version 4.1 of Bash, released in May, + 2010, was primarily a bugfix update. + + + + + The printf command + now accepts a option for setting array indices. + + + + Within double brackets, + the > and < + string comparison operators now conform to the locale. Since the locale setting may + affect the sorting order of string expressions, this + has side-effects on comparison tests within + [[ ... ]] expressions. + + + + The read builtin + now takes a option (read -N + chars), which causes the read + to terminate after chars + characters. + + + Reading N characters + &readn; + + + + + Here documents + embedded in + $( ... ) command substitution + constructs may terminate with a simple + ). + + + Using a <firstterm>here document</firstterm> + to set a variable + &herecommsub; + + + + + + + + + + Bash, version 4.2 + + Version 4.2 of Bash, released + in February, 2011, contains a number of new features and + enhancements, in addition to bugfixes. + + + + + Bash now supports the the + \u + and \U + Unicode escape. + + + Unicode is a cross-platform standard for encoding + into numerical values letters and graphic symbols. + This permits representing and displaying characters + in foreign alphabets and unusual fonts. + + +echo -e '\u2630' # Horizontal triple bar character. +# Equivalent to the more roundabout: +echo -e "\xE2\x98\xB0" + # Recognized by earlier Bash versions. + +echo -e '\u220F' # PI (Greek letter and mathematical symbol) +echo -e '\u0416' # Capital "ZHE" (Cyrillic letter) +echo -e '\u2708' # Airplane (Dingbat font) symbol + +echo -e "The amplifier circuit requires a 100 \u2126 pull-up resistor." + + +unicode_var='\u2640' +echo -e $unicode_var # Female symbol +printf "$unicode_var \n" # Female symbol, with newline + + +# And for something a bit more elaborate . . . + +# We can store Unicode symbols in an associative array, +#+ then retrieve them by name. +# Run this in a gnome-terminal or a terminal with a large, bold font +#+ for better legibility. + +declare -A symbol # Associative array. + +symbol[script_E]='\u2130' +symbol[script_F]='\u2131' +symbol[script_J]='\u2110' +symbol[script_M]='\u2133' +symbol[Rx]='\u211E' +symbol[TEL]='\u2121' +symbol[FAX]='\u213B' +symbol[care_of]='\u2105' +symbol[account]='\u2100' +symbol[trademark]='\u2122' + + +echo -ne "${symbol[script_E]} " +echo -ne "${symbol[script_F]} " +echo -ne "${symbol[script_J]} " +echo -ne "${symbol[script_M]} " +echo -ne "${symbol[Rx]} " +echo -ne "${symbol[TEL]} " +echo -ne "${symbol[FAX]} " +echo -ne "${symbol[care_of]} " +echo -ne "${symbol[account]} " +echo -ne "${symbol[trademark]} " +echo + + + The above example uses the + $' ... ' + string-expansion construct. + + + + + + + + When the lastpipe shell option + is set, the last command in a pipe doesn't run in a + subshell. + + + Piping input to a <link + linkend="readref">read</link> + &lastpipeopt; + + + This option offers possible fixups + for these example scripts: + and + . + + + + + + + + Negative array indices + permit counting backwards from the end of an array. + + + Negative array indices + &negarray; + + + + + + Substring extraction + uses a negative length parameter to + specify an offset from the end of the + target string. + + + Negative parameter in string-extraction + construct + &negoffset; + + + + + + + + + @@ -32179,19 +32791,21 @@ bad_command arg1 arg2 - How did I come to write a Bash scripting book? It's a strange + How did I come to write a scripting book? It's a strange tale. It seems that a few years back I needed to learn shell scripting -- and what better way to do that than to read a good book on the subject? I was looking to buy a tutorial and reference covering all aspects of the subject. I was looking for a book that would take difficult concepts, turn them inside out, and explain them in excruciating detail, with well-commented examples. - This is the notorious flog it to - death technique. + This is the notorious flog + it to death technique that works so well + with slow learners, eccentrics, odd ducks, fools and + geniuses. In fact, I was looking for this very book, or something very much like it. Unfortunately, it didn't exist, and if I wanted it, - I'd have to write it. And so, here we are, folks. + I'd have to write it. And so, here we are, folks. That reminds me of the apocryphal story about a mad professor. Crazy as a loon, the fellow was. At the sight of a @@ -32218,9 +32832,9 @@ bad_command arg1 arg2 The author claims no credentials or special qualifications, In fact, he is a school dropout - and has no formal credentials or qualifications - whatsoever. Aside from the ABS Guide, - his main claim to fame is a First Place in the sack + with no formal credentials or professional experience + whatsoever. None. Aside from the ABS Guide, + his major claim to fame is a First Place in the sack race at the Colfax Elementary School Field Day in June, 1958. other than a compulsion to write. @@ -32247,10 +32861,11 @@ bad_command arg1 arg2 word gaming list package, and the Quacky anagramming gaming package. He got off to a rather shaky start in the - computer game -- programming FORTRAN IV on a CDC 3800 -- - and is not the least bit nostalgic for those days. + computer game -- programming FORTRAN IV on a CDC 3800 (on paper coding + pads, no less) -- and is not the least bit nostalgic for those + days. - Living in a secluded desert community with wife and orange + Living in a secluded community with wife and orange tabby, he cherishes human frailty, especially his own. Sometimes it seems as if he has spent his entire life flouting conventional wisdom and defying the @@ -32266,28 +32881,31 @@ bad_command arg1 arg2 Where to Go For Help The author - will sometimes, if not too busy (and in a good mood), + will infrequently, if not too busy (and in a good mood), answer general scripting questions. E-mails from certain spam-infested TLDs (61, 202, 211, 218, 220, etc.) will be trapped by spam - filters and deleted unread. If your ISP is located on - one of these, please use a Webmail account to contact the - author. + filters and deleted unread. However, if you have a problem getting a specific script to work, you would be well advised to post to the comp.os.unix.shell Usenet newsgroup. - - If you need assistance with a schoolwork assignment, read - the pertinent sections of this and other reference works. - Do your best to solve the problem using your own wits and - resources. Kindly do not waste the author's time. You will get - neither help nor sympathy. - Well, if you absolutely - insist, you can try modifying to suit - your purposes. + + If you need assistance with a schoolwork assignment, + read the pertinent sections of this and other reference works. + Do your best to solve the problem using your own wits and + resources. Please do not waste the author's time. You will get + neither help nor sympathy. + Well, if you absolutely + insist, you can try modifying to suit + your purposes. + Likewise, kindly refrain from annoying the author + with solicitations, offers of employment, or business + opportunities. He is doing just fine, and requires + neither help nor sympathy, thank you. + ... sophisticated in mechanism but possibly agile @@ -32477,30 +33095,31 @@ bad_command arg1 arg2 Wayne Pollock, jipe, bojster, nyal, Hobbit, Ender, Little Monster (Alexis), Mark, - Patsie, Peggy Russell, Emilio Conti, Ian. D. Allen, - Hans-Joerg Diers, Arun Giridhar, Dennis Leeuw, Dan Jacobson, - Aurelio Marinho Jargas, Edward Scholtz, Jean Helou, Chris Martin, - Lee Maschmeyer, Bruno Haible, Wilbert Berendsen, Sebastien Godard, - Bjön Eriksson, John MacDonald, John Lange, Joshua Tschida, - Troy Engel, Manfred Schwarb, Amit Singh, Bill Gradwohl, - E. Choroba, David Lombard, Jason Parker, Steve Parker, Bruce - W. Clare, William Park, Vernia Damiano, Mihai Maties, Mark - Alexander, Jeremy Impson, Ken Fuchs, Jared Martin, Frank Wang, - Sylvain Fourmanoit, Matthew Sage, Matthew Walker, Kenny Stauffer, - Filip Moritz, Andrzej Stefanski, Daniel Albers, Stefano Palmeri, - Nils Radtke, Serghey Rodin, Jeroen Domburg, Alfredo Pironti, + Patsie, vladz, Peggy Russell, + Emilio Conti, Ian. D. Allen, Hans-Joerg Diers, Arun Giridhar, + Dennis Leeuw, Dan Jacobson, Aurelio Marinho Jargas, Edward + Scholtz, Jean Helou, Chris Martin, Lee Maschmeyer, Bruno Haible, + Wilbert Berendsen, Sebastien Godard, Bjön Eriksson, John + MacDonald, John Lange, Joshua Tschida, Troy Engel, Manfred + Schwarb, Amit Singh, Bill Gradwohl, E. Choroba, David Lombard, + Jason Parker, Steve Parker, Bruce W. Clare, William Park, Vernia + Damiano, Mihai Maties, Mark Alexander, Jeremy Impson, Ken Fuchs, + Jared Martin, Frank Wang, Sylvain Fourmanoit, Matthew Sage, + Matthew Walker, Kenny Stauffer, Filip Moritz, Andrzej Stefanski, + Daniel Albers, Jeffrey Haemer, Stefano Palmeri, Nils Radtke, + Sigurd Solaas, Serghey Rodin, 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, Dan Stromberg, Peter Knowles, Francisco Lobo, Mariusz - Gniazdowski, Sebastian Arming, Chetankumar Phulpagare, Benno - Schulenberg, Tedman Eng, Jochen DeSmet, Juan Nicolas Ruiz, - Oliver Beckstein, Achmed Darwish, Dotan Barak, Richard Neill, - Albert Siersema, Omair Eshkenazi, Geoff Lee, JuanJo Ciarlante, - Cliff Bamford, Nathan Coulter, Ramses Rodriguez Martinez, George - Dimitriu, Antonio Macchi, Tomas Pospisek, Andreas Kühne, - Pádraig Brady, and David Lawyer (himself an author of - four HOWTOs). + Chris Morgan, Walter Dnes, Linc Fessenden, Michael Iatrou, Pharis + Monalo, Jesse Gough, Fabian Kreutz, Mark Norman, Harald Koenig, + Dan Stromberg, Peter Knowles, Francisco Lobo, Mariusz Gniazdowski, + Sebastian Arming, Chetankumar Phulpagare, Benno Schulenberg, + Tedman Eng, Jochen DeSmet, Juan Nicolas Ruiz, Oliver Beckstein, + Achmed Darwish, Dotan Barak, Richard Neill, Albert Siersema, + Omair Eshkenazi, Geoff Lee, JuanJo Ciarlante, Cliff Bamford, + Nathan Coulter, Ramses Rodriguez Martinez, Evgeniy Ivanov, + George Dimitriu, Kevin LeBlanc, Antonio Macchi, Tomas Pospisek, + Andreas Kühne, Pádraig Brady, and David Lawyer + (himself an author of four HOWTOs). My gratitude to Chet Ramey and Brian Fox for writing Bash, @@ -33338,7 +33957,7 @@ bad_command arg1 arg2 url="http://www.dottocomu.com/b/archives/002571.html">Sony Librie e-book reader. This useful tool facilitates loading non-DRM user content on the Librie - (and the newer PRS-50X-series devices). + (and the newer PRS-xxx-series devices). @@ -33857,6 +34476,11 @@ bad_command arg1 arg2 &showallc; + + Base64 encoding/decoding + &base64; + + To end this section, a review of the basics . . . and more. @@ -33921,13 +34545,11 @@ bad_command arg1 arg2 - Number of command-line parameters passed to - script + Number of positional parameters - Number of command-line parameters passed to - script + Number of positional parameters @@ -34012,7 +34634,7 @@ bad_command arg1 arg2 Less than - Less than (ASCII) * + Less than (ASCII) * @@ -34216,8 +34838,8 @@ bad_command arg1 arg2 - Value of var, same as - $var + Value of var (same as + $var) @@ -34257,12 +34879,14 @@ bad_command arg1 arg2 If var not set, print - $ERR_MSG * + $ERR_MSG and abort script + with an exit status of 1.* If var not set, print - $ERR_MSG * + $ERR_MSG and abort script + with an exit status of 1.* @@ -34279,9 +34903,9 @@ bad_command arg1 arg2 - * Of course if var + * If var is set, evaluate the expression as - $var. + $var with no side-effects. @@ -34309,7 +34933,8 @@ bad_command arg1 arg2 Extract $length characters substring from $string - at $position + at $position [zero-indexed, + first character is at position 0] @@ -34380,39 +35005,41 @@ bad_command arg1 arg2 Numerical position in $string - of first character in $substring - that matches + of first character in $substring* + that matches [0 if no match, first character counts as + position 1] Extract $length characters from $string starting at - $position + $position [0 if no match, first + character counts as position 1] - Extract $substring* at - beginning of $string + Extract $substring*, searching + from beginning of $string - Extract $substring* at - beginning of $string + Extract $substring* , searching + from beginning of $string - Extract $substring* at - end of $string + Extract $substring*, searching + from end of $string - Extract $substring* at - end of $string + Extract $substring*, searching + from end of $string @@ -35771,11 +36398,11 @@ exit 0 Localization is an undocumented Bash feature. - A localized shell script echoes its text output in the - language defined as the system's locale. A Linux user in Berlin, - Germany, would get script output in German, whereas his cousin - in Berlin, Maryland, would get output from the same script in - English. + A localized shell script echoes + its text output in the language defined as the system's locale. + A Linux user in Berlin, Germany, would get script output in German, + whereas his cousin in Berlin, Maryland, would get output from + the same script in English. To create a localized script, use the following template to write all messages to the user (error messages, prompts, @@ -36063,7 +36690,8 @@ var=$(history); echo "$var" # $var is empty. - A Sample <filename>.bashrc</filename> File + Sample <filename>.bashrc</filename> and + <filename>.bash_profile</filename> Files The ~/.bashrc file determines the behavior of interactive shells. A good look at this file can @@ -36084,6 +36712,14 @@ var=$(history); echo "$var" # $var is empty. &bashrc; + And, here is a snippet from Andrzej Szelachowski's instructive + .bash_profile file. + + + <filename>.bash_profile</filename> file + &bashprof; + + @@ -36719,7 +37355,9 @@ do export SUM=$(($SUM + $(wc -l $f | awk '{ print $1 }'))); done; echo $SUMENTER. Finally, save the file to the flash drive after making certain the flash drive has properly mounted by parsing - the output of df. + the output of df. Note that + the flash drive must be unmounted + before it is removed. @@ -36809,6 +37447,8 @@ do export SUM=$(($SUM + $(wc -l $f | awk '{ print $1 }'))); done; echo $SUM/home/your-name) that have been modified in the last 24 hours. Hint: use find. + Optional: you may use this as the basis of a + backup script. @@ -36845,9 +37485,9 @@ do export SUM=$(($SUM + $(wc -l $f | awk '{ print $1 }'))); done; echo $SUMstdout or saving them to a file, along with the date and time the particular number set was generated. (If your script consistently generates - winning lottery numbers, then you can - retire on the proceeds and leave shell scripting to those - of us who have to work for a living.) + winning lottery numbers, then you + can retire on the proceeds and leave shell scripting to + those of us who have to work for a living.) @@ -36894,7 +37534,7 @@ do export SUM=$(($SUM + $(wc -l $f | awk '{ print $1 }'))); done; echo $SUM Removing Inactive Accounts - Inactive accounts on a network waste disk space and may + Inactive accounts on a network server waste disk space and may become a security risk. Write an administrative script (to be invoked by root or the cron daemon) that checks @@ -36908,14 +37548,14 @@ do export SUM=$(($SUM + $(wc -l $f | awk '{ print $1 }'))); done; echo $SUM Write a script for a multi-user system that checks users' disk usage. If a user surpasses a preset limit - (100 MB, for example) in her /home/username directory, - then the script automatically sends her a warning - e-mail. - The script will use the du and - mail commands. As an option, - it will allow setting and enforcing quotas using the quota and /home/username + directory, then the script automatically sends her a + pigout warning e-mail. The + script will use the du + and mail commands. As + an option, it will allow setting and enforcing quotas + using the quota and setquota commands. @@ -36982,7 +37622,7 @@ do export SUM=$(($SUM + $(wc -l $f | awk '{ print $1 }'))); done; echo $SUMAx^2 + Bx + C = 0. Have a script take as arguments the coefficients, A, B, and C, - and return the solutions to four decimal places. + and return the solutions to five decimal places. Hint: pipe the coefficients to bc, using the well-known formula, @@ -37003,6 +37643,22 @@ do export SUM=$(($SUM + $(wc -l $f | awk '{ print $1 }'))); done; echo $SUM + + Unicode Table + + Using as a template, + write a script that prints to a file a complete + Unicode table. + Hint: Use the option to + echo: + echo -e '\uXXXX', where + XXXX + is the Unicode numerical character designation. + This requires version 4.2 + or later of Bash. + + + Sum of Matching Numbers @@ -37091,12 +37747,12 @@ do export SUM=$(($SUM + $(wc -l $f | awk '{ print $1 }'))); done; echo $SUM Pretty-Printing a Data File - Certain database and spreadsheet packages use save-files - with comma-separated values - (CSVs). Other applications often need to parse these - files. - Given a data file with comma-separated fields, of the form: + Certain database and spreadsheet packages use + save-files with the fields separated by commas, commonly + referred to as comma-separated values + or CSVs. Other applications often need to parse these + files. Given a data file with comma-separated + fields, of the form: Jones,Bill,235 S. Williams St.,Denver,CO,80221,(303) 244-7989 Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612 ... @@ -37142,16 +37798,16 @@ Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612 You suspect that one particular user on the network - has been abusing his privileges and possibly attempting to + has been abusing her privileges and possibly attempting to hack the system. Write a script to automatically monitor - and log his activities when he's signed on. The log file + and log her activities when she's signed on. The log file will save entries for the previous week, and delete those entries more than seven days old. You may use last, lastlog, and lastcomm to aid your - surveillance of the suspected malefactor. + surveillance of the suspected fiend. @@ -37212,7 +37868,7 @@ Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612 Enable the script to check all the passwords on your - system. These probably do not reside in + system. These do not reside in /etc/passwd. @@ -37304,7 +37960,7 @@ done support for floating point numbers. So, the script writer needs to use bc or possibly awk to convert the - numbers and do the calculations. It may get rather messy + numbers and do the calculations. It could get rather messy . . . @@ -37320,8 +37976,8 @@ done class="directory">/etc during the course of a single day. This information should include the filename, user name, and access time. If any alterations to the - files take place, that should be flagged. Write this data - as neatly formatted records in a logfile. + files take place, that will be flagged. Write this data + as tabular (tab-separated) formatted records in a logfile. @@ -37343,16 +37999,16 @@ done Strip Comments Strip all comments from a shell script whose name - is specified on the command-line. Note that the #! line must not be stripped - out. + is specified on the command-line. Note that the initial + #! line must not be + stripped out. Strip HTML Tags - Strip all HTML tags from a specified HTML file, then + Strip all the HTML tags from a specified HTML file, then reformat it into lines between 60 and 75 characters in length. Reset paragraph and block spacing, as appropriate, and convert HTML tables to their approximate @@ -37364,6 +38020,7 @@ done XML Conversion Convert an XML file to both HTML and text format. + Optional: A script that converts Docbook/SGML to XML. @@ -37417,10 +38074,11 @@ done Morse Code - Convert a text file to Morse code. Each character of the - text file will be represented as a corresponding Morse - code group of dots and dashes (underscores), separated by - whitespace from the next. For example: + Convert a text string (or optionally a text file) to + Morse code. Each character of the string will be represented + as a corresponding Morse code group of dots and dashes + (underscores), separated by whitespace from the next. For + example: Invoke the "morse.sh" script with "script" as an argument to convert to Morse. @@ -37437,14 +38095,15 @@ s c r i p t Hex Dump Do a hex(adecimal) dump on a binary file - specified as an argument. The output should be in neat - tabular fields, with the - first field showing the address, each of the next 8 fields a - 4-byte hex number, and the final field the ASCII equivalent - of the previous 8 fields. The obvious - followup to this is to extend the hex dump script into a - disassembler. Using a lookup table, or some other clever - gimmick, convert the hex values into 80x86 op codes. + specified as an argument to the script. The output should + be in neat tabular fields, + with the first field showing the address, each of the + next 8 fields a 4-byte hex number, and the final field + the ASCII equivalent of the previous 8 fields. + The obvious followup to this is to extend the hex + dump script into a disassembler. Using a lookup table, + or some other clever gimmick, convert the hex values into + 80x86 op codes. @@ -37468,8 +38127,8 @@ s c r i p t Write a script that calculates determinants - For all you fine people who failed second-year algebra, - a determinant is a numerical quantity + For all you clever types who failed intermediate algebra, + a determinant is a numerical value associated with a multidimensional matrix (array of numbers). @@ -37737,7 +38396,7 @@ fairly detailed description of the Playfair Cipher and its solution methods.Please do not send the author your solutions to these exercises. There are more appropriate ways to impress him with your cleverness, such as submitting bugfixes and suggestions - for improving this book. + for improving the book. @@ -38068,6 +38727,11 @@ thegrendel@theriver.com 17 Mar 2010 ROWANBERRY release: Minor update. + + + 30 Apr 2011 + SWOZZLEBERRY release: Major update. + @@ -38100,7 +38764,7 @@ thegrendel@theriver.com track of major updates, user comments, and popularity ratings for the project. - The main hosting site for this document is the The legacy hosting site for this document is the Linux Documentation Project, which maintains many other Guides and HOWTOs as well. @@ -38129,18 +38793,7 @@ thegrendel@theriver.com (ksh). - - A primer on CGI programming, using Bash. - - Here is a simple CGI script to get you started. - - - Print the server environment - &testcgi; - - - @@ -38154,9 +38807,6 @@ thegrendel@theriver.com Guide is copyright 2000, by Mendel Cooper. - A printed edition of a substantively rewritten - version of the book will be released in fall of - 2010. The author also asserts copyright on all previous versions of this document. The author intends that this book be released @@ -38268,7 +38918,7 @@ distributors, or any of its associated software or documentation.Fedora is a trademark registered to Red Hat. Unix and UNIX are trademarks registered to the Open Group. MS Windows is a trademark registered to the Microsoft Corp. - Solaris is a trademark registered to Sun, Inc. + Solaris is a trademark registered to Oracle, Inc. OSX is a trademark registered to Apple, Inc. Yahoo is a trademark registered to Yahoo, Inc. Pentium is a trademark registered to Intel, Inc. diff --git a/LDP/guide/docbook/abs-guide/badread.sh b/LDP/guide/docbook/abs-guide/badread.sh index d74fd551..0d1172ff 100644 --- a/LDP/guide/docbook/abs-guide/badread.sh +++ b/LDP/guide/docbook/abs-guide/badread.sh @@ -3,6 +3,8 @@ # Attempting to use 'echo and 'read' #+ to assign variables non-interactively. +# shopt -s lastpipe + a=aaa b=bbb c=ccc @@ -16,6 +18,12 @@ echo "b = $b" # b = bbb echo "c = $c" # c = ccc # Reassignment failed. +### However . . . +## Uncommenting line 6: +# shopt -s lastpipe +##+ fixes the problem! +### This is a new feature in Bash, version 4.2. + # ------------------------------ # Try the following alternative. diff --git a/LDP/guide/docbook/abs-guide/base64.sh b/LDP/guide/docbook/abs-guide/base64.sh new file mode 100644 index 00000000..8721caca --- /dev/null +++ b/LDP/guide/docbook/abs-guide/base64.sh @@ -0,0 +1,129 @@ +#!/bin/bash +# base64.sh: Bash implementation of Base64 encoding and decoding. +# +# Copyright (c) 2011 vladz [vladz@devzero.fr] +# Used in ABSG with permission (thanks!). +# +# Encode or decode original Base64 (and also Base64url) +#+ from STDIN to STDOUT. +# +# Usage: +# +# Encode +# $ ./base64.sh < binary-file > binary-file.base64 +# Decode +# $ ./base64.sh -d < binary-file.base64 > binary-file +# +# Reference: +# +# [1] RFC4648 - "The Base16, Base32, and Base64 Data Encodings" +#  http://tools.ietf.org/html/rfc4648#section-5 + +# The base64_charset[] array contains entire base64 charset, +# and additionally the character "=" ... +base64_charset=( {A..Z} {a..z} {0..9} + / = ) + # Nice illustration of brace expansion. + +# Uncomment the ### line below to use base64url encoding instead of +#+ original base64. +### base64_charset=( {A..Z} {a..z} {0..9} - _ = ) + +# Output text width when encoding +#+ (64 characters, just like openssl output). +text_width=64 + +function display_base64_char { +#  Convert a 6-bit number (between 0 and 63) into its corresponding values +#+ in Base64, then display the result with the specified text width. + printf "${base64_charset[$1]}"; (( width++ )) + (( width % text_width == 0 )) && printf "\n" +} + +function encode_base64 { +# Encode three 8-bit hexadecimal codes into four 6-bit numbers. + # We need two local int array variables: + #  c8[]: to store the codes of the 8-bit characters to encode + # c6[]: to store the corresponding encoded values on 6-bit + declare -a -i c8 c6 + + # Convert hexadecimal to decimal. + c8=( $(printf "ibase=16; ${1:0:2}\n${1:2:2}\n${1:4:2}\n" | bc) ) + + #  Let's play with bitwise operators + #+ (3x8-bit into 4x6-bits conversion). + (( c6[0] = c8[0] >> 2 )) + (( c6[1] = ((c8[0] & 3) << 4) | (c8[1] >> 4) )) + + # The following operations depend on the c8 element number. + case ${#c8[*]} in + 3) (( c6[2] = ((c8[1] & 15) << 2) | (c8[2] >> 6) )) + (( c6[3] = c8[2] & 63 )) ;; + 2) (( c6[2] = (c8[1] & 15) << 2 )) + (( c6[3] = 64 )) ;; + 1) (( c6[2] = c6[3] = 64 )) ;; + esac + + for char in ${c6[@]}; do + display_base64_char ${char} + done +} + +function decode_base64 { +# Decode four base64 characters into three hexadecimal ASCII characters. + #  c8[]: to store the codes of the 8-bit characters + # c6[]: to store the corresponding Base64 values on 6-bit + declare -a -i c8 c6 + + # Find decimal value corresponding to the current base64 character. + for current_char in ${1:0:1} ${1:1:1} ${1:2:1} ${1:3:1}; do + [ "${current_char}" = "=" ] && break + + position=0 + while [ "${current_char}" != "${base64_charset[${position}]}" ]; do + (( position++ )) + done + + c6=( ${c6[*]} ${position} ) + done + + #  Let's play with bitwise operators + #+ (4x8-bit into 3x6-bits conversion). + (( c8[0] = (c6[0] << 2) | (c6[1] >> 4) )) + + # The next operations depends on the c6 elements number. + case ${#c6[*]} in + 3) (( c8[1] = ( (c6[1] & 15) << 4) | (c6[2] >> 2) )) + (( c8[2] = (c6[2] & 3) << 6 )); unset c8[2] ;; + 4) (( c8[1] = ( (c6[1] & 15) << 4) | (c6[2] >> 2) )) + (( c8[2] = ( (c6[2] & 3) << 6) | c6[3] )) ;; + esac + + for char in ${c8[*]}; do + printf "\x$(printf "%x" ${char})" + done +} + +# main () +if [ $# -eq 0 ]; then # encode + + # Make a hexdump of stdin and reformat in 3-byte groups. + content=$(cat - | xxd -ps -u | sed -r "s/(\w{6})/\1 /g" | + tr -d "\n") + + for chars in ${content}; do encode_base64 ${chars}; done + + echo + +elif [ "$1" = "-d" ]; then # decode + + # Reformat STDIN in pseudo 4x6-bit groups. + content=$(cat - | tr -d "\n" | sed -r "s/(.{4})/\1 /g") + + for chars in ${content}; do decode_base64 ${chars}; done + +else # display usage + echo + printf "Usage: $0 < Infile > Outfile\n" + printf " $0 -d < Infile > Outfile\n" + printf " -d decode\n\n" +fi diff --git a/LDP/guide/docbook/abs-guide/bash-profile.snippet b/LDP/guide/docbook/abs-guide/bash-profile.snippet new file mode 100644 index 00000000..813013d0 --- /dev/null +++ b/LDP/guide/docbook/abs-guide/bash-profile.snippet @@ -0,0 +1,51 @@ +# From Andrzej Szelachowski's ~/.bash_profile: + + +# Note that a variable may require special treatment +#+ if it will be exported. + +DARKGRAY='\e[1;30m' +LIGHTRED='\e[1;31m' +GREEN='\e[32m' +YELLOW='\e[1;33m' +LIGHTBLUE='\e[1;34m' +NC='\e[m' + +PCT="\`if [[ \$EUID -eq 0 ]]; then T='$LIGHTRED' ; else T='$LIGHTBLUE'; fi; +echo \$T \`" + +# For "literal" command substitution to be assigned to a variable, +#+ use escapes and double quotes: +#+ PCT="\` ... \`" . . . +# Otherwise, the value of PCT variable is assigned only once, +#+ when the variable is exported/read from .bash_profile, +#+ and it will not change afterwards even if the user ID changes. + + +PS1="\n$GREEN[\w] \n$DARKGRAY($PCT\t$DARKGRAY)-($PCT\u$DARKGRAY)-($PCT\! +$DARKGRAY)$YELLOW-> $NC" + +# Escape a variables whose value changes: +# if [[ \$EUID -eq 0 ]], +# Otherwise the value of the EUID variable will be assigned only once, +#+ as above. + +# When a variable is assigned, it should be called escaped: +#+ echo \$T, +# Otherwise the value of the T variable is taken from the moment the PCT +#+ variable is exported/read from .bash_profile. +# So, in this example it would be null. + +# When a variable's value contains a semicolon it should be strong quoted: +# T='$LIGHTRED', +# Otherwise, the semicolon will be interpreted as a command separator. + + +# Variables PCT and PS1 can be merged into a new PS1 variable: + +PS1="\`if [[ \$EUID -eq 0 ]]; then PCT='$LIGHTRED'; +else PCT='$LIGHTBLUE'; fi; +echo '\n$GREEN[\w] \n$DARKGRAY('\$PCT'\t$DARKGRAY)-\ +('\$PCT'\u$DARKGRAY)-('\$PCT'\!$DARKGRAY)$YELLOW-> $NC'\`" + +# The trick is to use strong quoting for parts of old PS1 variable. diff --git a/LDP/guide/docbook/abs-guide/connect-stat.sh b/LDP/guide/docbook/abs-guide/connect-stat.sh index c2928188..b1e365c1 100644 --- a/LDP/guide/docbook/abs-guide/connect-stat.sh +++ b/LDP/guide/docbook/abs-guide/connect-stat.sh @@ -1,8 +1,11 @@ #!/bin/bash +# connect-stat.sh +# Note that this script may need modification +#+ to work with a wireless connection. PROCNAME=pppd # ppp daemon PROCFILENAME=status # Where to look. -NOTCONNECTED=65 +NOTCONNECTED=85 INTERVAL=2 # Update every 2 seconds. pidno=$( ps ax | grep -v "ps ax" | grep -v grep | grep $PROCNAME | @@ -22,7 +25,7 @@ awk '{ print $1 }' ) if [ -z "$pidno" ] # If no pid, then process is not running. then echo "Not connected." - exit $NOTCONNECTED +# exit $NOTCONNECTED else echo "Connected."; echo fi @@ -34,7 +37,7 @@ do # While process running, then "status" file exists. then echo "Disconnected." - exit $NOTCONNECTED +# exit $NOTCONNECTED fi netstat -s | grep "packets received" # Get some connect statistics. @@ -54,3 +57,4 @@ exit 0 # --------- # Improve the script so it exits on a "q" keystroke. # Make the script more user-friendly in other ways. +# Fix the script to work with wireless/DSL connections. diff --git a/LDP/guide/docbook/abs-guide/escaped.sh b/LDP/guide/docbook/abs-guide/escaped.sh index 5becbaf6..0282d109 100644 --- a/LDP/guide/docbook/abs-guide/escaped.sh +++ b/LDP/guide/docbook/abs-guide/escaped.sh @@ -3,6 +3,10 @@ echo; echo +############################################################# +### First, let's show some basic escaped-character usage. ### +############################################################# + # Escaping a newline. # ------------------ @@ -33,28 +37,40 @@ echo "QUOTATION MARK" echo -e "\042" # Prints " (quote, octal ASCII character 42). echo "==============" + + # The $'\X' construct makes the -e option unnecessary. + echo; echo "NEWLINE AND BEEP" echo $'\n' # Newline. echo $'\a' # Alert (beep). -echo "===============" +echo "---------------" echo "QUOTATION MARKS" -# Version 2 and later of Bash permits using the $'\nnn' construct. -# Note that in this case, '\nnn' is an octal value. +echo "---------------" +echo; echo; echo +# Here we have seen $'\nnn" string expansion. + +# =================================================================== # +# Version 2 of Bash introduced the $'\nnn' string expansion construct. +# =================================================================== # + +echo "Introducing the \$\' ... \' string-expansion construct!" +echo + echo $'\t \042 \t' # Quote (") framed by tabs. +# Note that '\nnn' is an octal value. # It also works with hexadecimal values, in an $'\xhhh' construct. echo $'\t \x22 \t' # Quote (") framed by tabs. # Thank you, Greg Keraunen, for pointing this out. # Earlier Bash versions allowed '\x022'. + echo "===============" echo - - # Assigning ASCII characters to a variable. # ---------------------------------------- quote=$'\042' # " assigned to a variable. diff --git a/LDP/guide/docbook/abs-guide/ex1.sh b/LDP/guide/docbook/abs-guide/ex1.sh index cd43d983..f55896df 100644 --- a/LDP/guide/docbook/abs-guide/ex1.sh +++ b/LDP/guide/docbook/abs-guide/ex1.sh @@ -4,4 +4,4 @@ cd /var/log cat /dev/null > messages cat /dev/null > wtmp -echo "Logs cleaned up." +echo "Log files cleaned up." diff --git a/LDP/guide/docbook/abs-guide/ex1a.sh b/LDP/guide/docbook/abs-guide/ex1a.sh index 0d1fc587..cd8efd96 100644 --- a/LDP/guide/docbook/abs-guide/ex1a.sh +++ b/LDP/guide/docbook/abs-guide/ex1a.sh @@ -16,4 +16,6 @@ cat /dev/null > wtmp echo "Logs cleaned up." -exit # The right and proper method of "exiting" from a script. +exit # The right and proper method of "exiting" from a script. + # A bare "exit" (no parameter) returns the exit status + #+ of the preceding command. diff --git a/LDP/guide/docbook/abs-guide/ex2.sh b/LDP/guide/docbook/abs-guide/ex2.sh index b7661f0a..89a59945 100644 --- a/LDP/guide/docbook/abs-guide/ex2.sh +++ b/LDP/guide/docbook/abs-guide/ex2.sh @@ -75,7 +75,9 @@ mv mesg.temp messages # Becomes new log directory. #* No longer needed, as the above method is safer. cat /dev/null > wtmp # ': > wtmp' and '> wtmp' have the same effect. -echo "Logs cleaned up." +echo "Log files cleaned up." +# Note that there are other log files in /var/log not affected +#+ by this script. exit 0 # A zero return value from the script upon exit indicates success diff --git a/LDP/guide/docbook/abs-guide/fetch_address-2.sh b/LDP/guide/docbook/abs-guide/fetch_address-2.sh index 6d94adf3..1c6480bc 100644 --- a/LDP/guide/docbook/abs-guide/fetch_address-2.sh +++ b/LDP/guide/docbook/abs-guide/fetch_address-2.sh @@ -29,21 +29,21 @@ fetch_address () } -store_address "Charles Jones" "414 W. 10th Ave., Baltimore, MD 21236" -store_address "John Smith" "202 E. 3rd St., New York, NY 10009" -store_address "Wilma Wilson" "1854 Vermont Ave, Los Angeles, CA 90023" +store_address "Lucas Fayne" "414 W. 13th Ave., Baltimore, MD 21236" +store_address "Arvid Boyce" "202 E. 3rd St., New York, NY 10009" +store_address "Velma Winston" "1854 Vermont Ave, Los Angeles, CA 90023" # Exercise: # Rewrite the above store_address calls to read data from a file, #+ then assign field 1 to name, field 2 to address in the array. # Each line in the file would have a format corresponding to the above. # Use a while-read loop to read from file, sed or awk to parse the fields. -fetch_address "Charles Jones" -# Charles Jones's address is 414 W. 10th Ave., Baltimore, MD 21236. -fetch_address "Wilma Wilson" -# Wilma Wilson's address is 1854 Vermont Ave, Los Angeles, CA 90023. -fetch_address "John Smith" -# John Smith's address is 202 E. 3rd St., New York, NY 10009. +fetch_address "Lucas Fayne" +# Lucas Fayne's address is 414 W. 13th Ave., Baltimore, MD 21236. +fetch_address "Velma Winston" +# Velma Winston's address is 1854 Vermont Ave, Los Angeles, CA 90023. +fetch_address "Arvid Boyce" +# Arvid Boyce's address is 202 E. 3rd St., New York, NY 10009. fetch_address "Bozo Bozeman" # Bozo Bozeman's address is not in database. diff --git a/LDP/guide/docbook/abs-guide/fetch_address.sh b/LDP/guide/docbook/abs-guide/fetch_address.sh index 7cae768f..5ce8b341 100644 --- a/LDP/guide/docbook/abs-guide/fetch_address.sh +++ b/LDP/guide/docbook/abs-guide/fetch_address.sh @@ -15,3 +15,8 @@ echo "Wilma's address is ${address[Wilma]}." # Wilma's address is 1854 Vermont Ave, Los Angeles, CA 90023. echo "John's address is ${address[John]}." # John's address is 202 E. 3rd St., New York, NY 10009. + +echo + +echo "${!address[*]}" # The array indices ... +# Charles John Wilma diff --git a/LDP/guide/docbook/abs-guide/hanoi2.bash b/LDP/guide/docbook/abs-guide/hanoi2.bash index bbabe851..1a0d1d42 100644 --- a/LDP/guide/docbook/abs-guide/hanoi2.bash +++ b/LDP/guide/docbook/abs-guide/hanoi2.bash @@ -16,10 +16,10 @@ ### Variables && sanity check ### E_NOPARAM=86 -E_BADPARAM=87 # Illegal no. of disks passed to script. +E_BADPARAM=87 # Illegal no. of disks passed to script. E_NOEXIT=88 -DISKS=${1:-E_NOPARAM} # Must specify how many disks. +DISKS=${1:-$E_NOPARAM} # Must specify how many disks. Moves=0 MWIDTH=7 diff --git a/LDP/guide/docbook/abs-guide/here-commsub.sh b/LDP/guide/docbook/abs-guide/here-commsub.sh new file mode 100644 index 00000000..04dcfe29 --- /dev/null +++ b/LDP/guide/docbook/abs-guide/here-commsub.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# here-commsub.sh +# Requires Bash version -ge 4.1 ... + +multi_line_var=$( cat <<ENDxxx +------------------------------ +This is line 1 of the variable +This is line 2 of the variable +This is line 3 of the variable +------------------------------ +ENDxxx) + +# Rather than what Bash 4.0 requires: +#+ that the terminating limit string and +#+ the terminating close-parenthesis be on separate lines. + +# ENDxxx +# ) + + +echo "$multi_line_var" + +# Bash still emits a warning, though. +# warning: here-document at line 10 delimited +#+ by end-of-file (wanted `ENDxxx') diff --git a/LDP/guide/docbook/abs-guide/ip-addresses.sh b/LDP/guide/docbook/abs-guide/ip-addresses.sh new file mode 100644 index 00000000..638c321b --- /dev/null +++ b/LDP/guide/docbook/abs-guide/ip-addresses.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# ip-addresses.sh +# List the IP addresses your computer is connected to. + +# Inspired by Greg Bledsoe's ddos.sh script, +# Linux Journal, 09 March 2011. +# URL: +# http://www.linuxjournal.com/content/back-dead-simple-bash-complex-ddos +# Greg licensed his script under the GPL2, +#+ and as a derivative, this script is likewise GPL2. + +connection_type=TCP # Also try UDP. +field=2 # Which field of the output we're interested in. +no_match=LISTEN # Filter out records containing this. Why? +lsof_args=-ni # -i lists Internet-associated files. + # -n preserves numerical IP addresses. + # What happens without the -n option? Try it. +router="[0-9][0-9][0-9][0-9][0-9]->" +# Delete the router info. + +lsof "$lsof_args" | grep $connection_type | grep -v "$no_match" | + awk '{print $9}' | cut -d : -f $field | sort | uniq | + sed s/"^$router"// + +# Bledsoe's script assigns the output of a filtered IP list, +# (similar to lines 19-22, above) to a variable. +# He checks for multiple connections to a single IP address, +# then uses: +# +# iptables -I INPUT -s $ip -p tcp -j REJECT --reject-with tcp-reset +# +# ... within a 60-second delay loop to bounce packets from DDOS attacks. + + +# Exercise: +# -------- +# Use the 'iptables' command to extend this script +#+ to reject connection attempts from well-known spammer IP domains. diff --git a/LDP/guide/docbook/abs-guide/lastpipe-option.sh b/LDP/guide/docbook/abs-guide/lastpipe-option.sh new file mode 100644 index 00000000..1db45026 --- /dev/null +++ b/LDP/guide/docbook/abs-guide/lastpipe-option.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# lastpipe-option.sh + +line='' # Null value. +echo "\$line = "$line"" # $line = + +echo + +shopt -s lastpipe # Error on Bash version -lt 4.2. +echo "Exit status of attempting to set \"lastpipe\" option is $?" +# 1 if Bash version -lt 4.2, 0 otherwise. + +echo + +head -1 $0 | read line # Pipe the first line of the script to read. +# ^^^^^^^^^ Not in a subshell!!! + +echo "\$line = "$line"" +# Older Bash releases $line = +# Bash version 4.2 $line = #!/bin/bash diff --git a/LDP/guide/docbook/abs-guide/max.sh b/LDP/guide/docbook/abs-guide/max.sh index 8898eec8..bf2bdb09 100644 --- a/LDP/guide/docbook/abs-guide/max.sh +++ b/LDP/guide/docbook/abs-guide/max.sh @@ -7,7 +7,7 @@ EQUAL=251 # Return value if both params equal. #+ params that might be fed to the function. max2 () # Returns larger of two numbers. -{ # Note: numbers compared must be less than 257. +{ # Note: numbers compared must be less than 250. if [ -z "$2" ] then return $E_PARAM_ERR diff --git a/LDP/guide/docbook/abs-guide/neg-array.sh b/LDP/guide/docbook/abs-guide/neg-array.sh new file mode 100644 index 00000000..af225aa4 --- /dev/null +++ b/LDP/guide/docbook/abs-guide/neg-array.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# neg-array.sh +# Requires Bash, version -ge 4.2. + +array=( zero one two three four five ) # Six-element array. + +# Negative array indices now permitted. +echo ${array[-1]} # five +echo ${array[-2]} # four +# ... +echo ${array[-6]} # zero +# Negative array indices count backward from the last element+1. + +# But, you cannot index past the beginning of the array. +echo ${array[-7]} # array: bad array subscript + + +# So, what is this new feature good for? + +echo "The last element in the array is "${array[-1]}"" +# Which is quite a bit more straightforward than: +echo "The last element in the array is "${array[${#array[*]}-1]}"" +echo + +# And ... + +index=0 +let "neg_element_count = 0 - ${#array[*]}" +# Number of elements, converted to a negative number. + +while [ $index -gt $neg_element_count ]; do + ((index--)); echo -n "${array[index]} " +done # Lists the elements in the array, backwards. + # We have just simulated the "tac" command on this array. + +echo diff --git a/LDP/guide/docbook/abs-guide/neg-offset.sh b/LDP/guide/docbook/abs-guide/neg-offset.sh new file mode 100644 index 00000000..ba2891cc --- /dev/null +++ b/LDP/guide/docbook/abs-guide/neg-offset.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Bash, version -ge 4.2 +# Negative length-index in substring extraction. +# Important: This changes the interpretation of this construct! + +stringZ=abcABC123ABCabc + +echo ${stringZ} # abcABC123ABCabc +echo ${stringZ:2:3} # cAB +# Count 2 chars forward from string beginning, and extract 3 chars. +# ${string:position:length} + +# So far, nothing new, but now ... + +echo ${stringZ:3:-6} # ABC123 +# ^ +# Index 3 chars forward from beginning and 6 chars backward from end, +#+ and extract everything in between. +# ${string:offset-from-front:offset-from-end} +# When the "length" parameter is negative, +#+ it serves as an "offset-from-end" parameter. diff --git a/LDP/guide/docbook/abs-guide/numbers.sh b/LDP/guide/docbook/abs-guide/numbers.sh index 1a734b97..3f4ac235 100644 --- a/LDP/guide/docbook/abs-guide/numbers.sh +++ b/LDP/guide/docbook/abs-guide/numbers.sh @@ -57,8 +57,6 @@ let "bad_oct = 081" # bad_oct = 081: value too great for base (error token is "081") # Octal numbers use only digits in the range 0 - 7. -exit $? # Thanks, Rich Bartell and Stephane Chazelas, for clarification. +exit $? # Exit value = 1 (error) -$ sh numbers.sh -$ echo $? -$ 1 +# Thanks, Rich Bartell and Stephane Chazelas, for clarification. diff --git a/LDP/guide/docbook/abs-guide/psub.bash b/LDP/guide/docbook/abs-guide/psub.bash new file mode 100644 index 00000000..91aad498 --- /dev/null +++ b/LDP/guide/docbook/abs-guide/psub.bash @@ -0,0 +1,20 @@ +#!/bin/bash +# psub.bash + +# As inspired by Diego Molina (thanks!). + +declare -a array0 +while read +do + array0[${#array0[@]}]="$REPLY" +done < <( sed -e 's/bash/CRASH-BANG!/' $0 | grep bin | awk '{print $1}' ) + +echo "${array0[@]}" + +exit $? + +# ====================================== # + +bash psub.bash + +#!/bin/CRASH-BANG! done #!/bin/CRASH-BANG! diff --git a/LDP/guide/docbook/abs-guide/random-between.sh b/LDP/guide/docbook/abs-guide/random-between.sh index b97453f7..cef767d0 100644 --- a/LDP/guide/docbook/abs-guide/random-between.sh +++ b/LDP/guide/docbook/abs-guide/random-between.sh @@ -2,6 +2,7 @@ # random-between.sh # Random number between two specified values. # Script by Bill Gradwohl, with minor modifications by the document author. +# Corrections in lines 187 and 189 by Anthony Le Clezio. # Used with permission. @@ -184,9 +185,9 @@ done # Let's check the results for ((i=${minimum}; i<=${maximum}; i+=divisibleBy)); do - [ ${answer[i+displacement]} -eq 0 ] \ + [ ${answer[i+disp]} -eq 0 ] \ && echo "We never got an answer of $i." \ - || echo "${i} occurred ${answer[i+displacement]} times." + || echo "${i} occurred ${answer[i+disp]} times." done diff --git a/LDP/guide/docbook/abs-guide/read-N.sh b/LDP/guide/docbook/abs-guide/read-N.sh new file mode 100644 index 00000000..67a81130 --- /dev/null +++ b/LDP/guide/docbook/abs-guide/read-N.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# Requires Bash version -ge 4.1 ... + +num_chars=61 + +read -N $num_chars var < $0 # Read first 61 characters of script! +echo "$var" +exit + +####### Output of Script ####### + +#!/bin/bash +# Requires Bash version -ge 4.1 ... + +num_chars=61 diff --git a/LDP/guide/docbook/abs-guide/readpipe.sh b/LDP/guide/docbook/abs-guide/readpipe.sh index 9f48d24b..6f32634a 100644 --- a/LDP/guide/docbook/abs-guide/readpipe.sh +++ b/LDP/guide/docbook/abs-guide/readpipe.sh @@ -2,6 +2,8 @@ # readpipe.sh # This example contributed by Bjon Eriksson. +### shopt -s lastpipe + last="(null)" cat $0 | while read line @@ -12,7 +14,9 @@ done echo echo "++++++++++++++++++++++" -printf "\nAll done, last: $last\n" +printf "\nAll done, last: $last\n" # The output of this line + #+ changes if you uncomment line 5. + # (Bash, version -ge 4.2 required.) exit 0 # End of code. # (Partial) output of script follows. diff --git a/LDP/guide/docbook/abs-guide/realname.sh b/LDP/guide/docbook/abs-guide/realname.sh index 77daedcc..1ce57697 100644 --- a/LDP/guide/docbook/abs-guide/realname.sh +++ b/LDP/guide/docbook/abs-guide/realname.sh @@ -5,7 +5,7 @@ ARGCOUNT=1 # Expect one arg. -E_WRONGARGS=65 +E_WRONGARGS=85 file=/etc/passwd pattern=$1 diff --git a/LDP/guide/docbook/abs-guide/resistor-inventory.sh b/LDP/guide/docbook/abs-guide/resistor-inventory.sh index 1a7cc915..7116e211 100644 --- a/LDP/guide/docbook/abs-guide/resistor-inventory.sh +++ b/LDP/guide/docbook/abs-guide/resistor-inventory.sh @@ -45,6 +45,7 @@ do # Now, retrieve value, using indirect referencing. echo "There are ${!Inv} of [${!Val} ohm / ${!Pdissip} watt]\ resistors in stock." # ^ ^ + # As of Bash 4.2, you can replace "ohm" with \u2126 (using echo -e). echo "These are located in bin # ${!Loc}." echo "Their color code is \"${!Ccode}\"." diff --git a/LDP/guide/docbook/abs-guide/test-cgi.sh b/LDP/guide/docbook/abs-guide/test-cgi.sh index e2307e06..2f578c42 100644 --- a/LDP/guide/docbook/abs-guide/test-cgi.sh +++ b/LDP/guide/docbook/abs-guide/test-cgi.sh @@ -1,13 +1,12 @@ #!/bin/bash -# May have to change the location for your site. -# (At the ISP's servers, Bash may not be in the usual place.) -# Other places: /usr/bin or /usr/local/bin -# Might even try it without any path in sha-bang. - # test-cgi.sh # by Michael Zick # Used with permission +# May have to change the location for your site. +# (At the ISP's servers, Bash may not be in the usual place.) +# Other places: /usr/bin or /usr/local/bin +# Might even try it without any path in sha-bang. # Disable filename globbing. set -f