This commit is contained in:
gferg 2002-07-22 15:11:51 +00:00
parent 9e6d6d08a8
commit 77c6f1f451
32 changed files with 1614 additions and 352 deletions

View File

@ -3,7 +3,141 @@ RELEASE HISTORY
Change log
Version 1.4
Version 1.5 (major update)
'PAPAYA' release
07/13/02
1) In "Basic Commands" section of "External Commands and Filters"
Added "man, info" entry.
At "ls," added comments to "ex40.sh" example.
2) In "File and Archiving Commands" section of "External Commands and Filters"
section:
Moved "shred" to "Utilities" subsection and did minor rewriting of entry.
Fixed minor error in "de-rpm.sh" example.
Added "mktemp" entry.
Added "rpm" entry, with usage examples.
Added "rpm2cpio" entry.
3) In "Math Commands" section of "External Commands" chapter:
Split "bc" and "dc" into separate entries.
At "bc", added "cannon.sh" example.
4) In "Miscellaneous Commands" section of "External Commands" Chapter:
At "mcookie" entry, added "tempfile-name.sh" example.
At "seq" entry, added section to "ex53.sh" example.
Added "units" entry, with "unit-conversion.sh" example.
Added "doexec" entry.
More info at "pathchk" entry.
5) In "Communications Commands" section of "External Commands" chapter:
Added usage example at "host" entry.
Revised "finger" entry.
Added "ipcalc" entry.
Added "mailto" entry.
Added "wget" entry.
Added "lynx" (with "-dump" option) entry.
More info at "nslookup."
More info at "dig."
More info at "traceroute."
6) In "Time/Date Commands" section of "External Commands" chapter:
More info at "usleep" entry.
7) In "Terminal Control Commands" section of "External Commands" chapter:
Added more options at "tput" entry.
Added "infocmp" entry, with usage example.
8) In "File and Archive Commands" section of "External Commands" Chapter:
Added info at "diff" entry.
9) In "Complex Commands" section of "External Commands" Chapter:
At "find" entry, clarified introductory remarks, and added info.
10) In "Internal Commands and Builtins" chapter:
At "source" entry, added "self-source.sh" example.
At "shopt" entry, fixed up usage example.
11) In "Job Control Commands" section of "Internal Commands":
Added comments to "self-destruct.sh" example.
12) In "Testing and Branching" subsection of "Loops and Branches" chapter,
Improved "isalpha.sh" example (added integer test function).
13) In "System and Administrative Commands" chapter:
Added "passwd" entry, with in-line illustrative script.
Added "readelf" entry.
Added "size" entry.
More discussion in "Modules" subsection.
Added usage example at "dmesg" entry.
14) In "Assorted Tips" section of "Miscellany" chapter:
Added "Colorizing Scripts" section, with "ex30a.sh" and
"color-echo.sh" examples.
Added "agram.sh" example of iterated piping to a filter.
15) In "Optimizations" section of "Miscellany" chapter:
Added "avoiding unnecessary commands."
16) In "Arrays" chapter:
Added "poem.sh" example.
17) In "Regular Expressions" chapter:
Clarifications and error corrections on "Extended Regular Expressions"
section (thanks, Peter Tillier).
18) In "Tests" chapter:
Added code to "arith-tests.sh" example.
19) In "Parameter Substitution" chapter:
At "${parameter-default}", added usage when command-line parameters in a
script are "missing."
At "${paramter?err_msg}", added "usage-msg.sh" example.
20) In "Functions" chapter:
Added info to "ex60.sh" example.
21) In "Gotchas" chapter:
Added material to "badread.sh" example.
22) In "Special Characters" chapter:
Added usage examples at "*" entry.
23) In "Variable Substitution" section of "Introduction to Variables" chapter:
Added in-line example of using uninitialized variable in arithmetic
operations.
24) In "Bash Variables are Untyped" section of "Introduction to Variables"
chapter:
Rewrote "int-or-string.sh" example.
25) Renamed "Oddities" section of "Miscellany" chapter to "Recursion",
and moved it forward.
26) In "Starting off with a Sha-Bang" chapter:
Added commentary and script snippet to footnote [2].
27) Slight revision to introduction to the book.
28) In "Contributed Scripts" appendix:
Added "soundex.sh" example.
Fixed minor typo in lead-in to "obj-oriented.sh" example.
29) In "Writing Scripts" section of "Exercises" appendix:
Added "Justification" exercise to "Intermediate" section.
Added "Buffon's Needle" exercise to "Difficult" section.
Added "Chasing Spammers" exercise to "Difficult" section.
30) In "Bibliography" section:
Added Steve Parker entry.
31) Added Landon Noll epigraph to end of "Scripting With Style" chapter.
32) Various minor cleanups and additions to example scripts.
Version 1.4 (minor update)
'MANGO' release
06/16/02
@ -105,7 +239,6 @@ Version 1.3
Added "sum matching numbers" exercise.
5) In "Oddities" section of "Miscellany" chapter:
Added "Security Issues" section.
Added Rick Boivie's "pb.sh" script as a recursive script example.
6) In "Optimizations" section of "Miscellany" chapter:
@ -212,18 +345,21 @@ Version 1.3
30) Fixed reference links to "startup files" section.
31) In "Bibliography" section:
31) In "Miscellany" Chapter:
Added "Security Issues" section.
32) In "Bibliography" section:
Added Denning entry.
Added Polya entry.
Added "Shell Corner" entry.
Added "UNIX Grymoire" entry.
32) In "Copyright" appendix:
33) In "Copyright" appendix:
Clarified license terms with reference to "Open Publication License."
33) Various minor fixups and enhancements to example scripts.
34) Various minor fixups and enhancements to example scripts.
34) Updated references to LDP site (changed from 'linuxdoc.org' to
35) Updated references to LDP site (changed from 'linuxdoc.org' to
'tldp.org').

File diff suppressed because it is too large Load Diff

View File

@ -5,15 +5,32 @@
# Exit status opposite from [ ... ] construct!
(( 0 ))
echo "Exit status of \"(( 0 ))\" is $?." # 1
echo "Exit status of \"(( 0 ))\" is $?." # 1
(( 1 ))
echo "Exit status of \"(( 1 ))\" is $?." # 0
echo "Exit status of \"(( 1 ))\" is $?." # 0
(( 5 > 4 )) # true
echo $? # 0
(( 5 > 4 )) # true
echo "Exit status of \"(( 5 > 4 ))\" is $?." # 0
(( 5 > 9 )) # false
echo $? # 1
(( 5 > 9 )) # false
echo "Exit status of \"(( 5 > 9 ))\" is $?." # 1
(( 5 - 5 )) # 0
echo "Exit status of \"(( 5 - 5 ))\" is $?." # 1
(( 5 / 4 )) # Division o.k.
echo "Exit status of \"(( 5 / 4 ))\" is $?." # 0
(( 1 / 2 )) # Division result < 1.
echo "Exit status of \"(( 1 / 2 ))\" is $?." # Rounded off to 0.
# 1
(( 1 / 0 )) 2>/dev/null # Illegal division by 0.
echo "Exit status of \"(( 1 / 0 ))\" is $?." # 1
# What effect does the "2>/dev/null" have?
# What would happen if it were removed?
# Try removing it, then rerunning the script.
exit 0

View File

@ -10,6 +10,7 @@ c=ccc
echo "one two three" | read a b c
# Try to reassign a, b, and c.
echo
echo "a = $a" # a = aaa
echo "b = $b" # b = bbb
echo "c = $c" # c = ccc
@ -29,4 +30,26 @@ echo "b = $b" # b = two
echo "c = $c" # c = three
# Reassignment succeeded.
# ------------------------------
# Note also that an echo to a 'read' works within a subshell.
# However, the value of the variable changes *only* within the subshell.
a=aaa # Starting all over again.
b=bbb
c=ccc
echo; echo
echo "one two three" | ( read a b c;
echo "Inside subshell: "; echo "a = $a"; echo "b = $b"; echo "c = $c" )
# a = one
# b = two
# c = three
echo "-----------------"
echo "Outside subshell: "
echo "a = $a" # a = aaa
echo "b = $b" # b = bbb
echo "c = $c" # c = ccc
echo
exit 0

View File

@ -20,22 +20,16 @@
#+ an operation that feeds its output back into the input.
# Sometimes the result is a "chaotic" series.
ARGS=1
E_BADARGS=65
if [ $# -ne $ARGS ] # Need a seed number.
then
echo "Usage: `basename $0` NUMBER"
exit $E_BADARGS
fi
MAX_ITERATIONS=200
# For large seed numbers (&gt;32000), increase MAX_ITERATIONS.
h=$1 # Seed
h=${1:-$$} # Seed
# Use $PID as seed,
#+ if not specified as command-line arg.
echo
echo "C($1) --- $MAX_ITERATIONS Iterations"
echo "C($h) --- $MAX_ITERATIONS Iterations"
echo
for ((i=1; i<=MAX_ITERATIONS; i++))

View File

@ -1,19 +1,20 @@
#!/bin/bash
# de-rpm.sh: Unpack an 'rpm' archive
E_NO_ARGS=65
: ${1?"Usage: `basename $0` target-file"}
# Must specify 'rpm' archive name as an argument.
TEMPFILE=$$.cpio # Tempfile with "unique" name.
# $$ is process ID of script.
if [ -z "$1" ]
then
echo "Usage: `basename $0` filename"
exit $E_NO_ARGS
fi
rpm2cpio < $1 > $TEMPFILE # Converts rpm archive into cpio archive.
cpio --make-directories -F $TEMPFILE -i # Unpacks cpio archive.
rm -f $TEMPFILE # Deletes cpio archive.
exit 0
# Exercise:
# Add check for whether 1) "target-file" exists and
#+ 2) it is really an rpm archive.
# Hint: parse output of 'file' command.

View File

@ -11,6 +11,8 @@ b=5
#+ whose value consists of all-integer characters.
# Caution advised.
echo
if [ "$a" -ne "$b" ]
then
echo "$a is not equal to $b"
@ -23,9 +25,11 @@ if [ "$a" != "$b" ]
then
echo "$a is not equal to $b."
echo "(string comparison)"
# "4" != "5"
# ASCII 52 != ASCII 53
fi
# In this instance, both "-ne" and "!=" work.
# In this particular instance, both "-ne" and "!=" work.
echo

View File

@ -1,4 +1,5 @@
#!/bin/bash
# Naked variables
echo
@ -7,16 +8,16 @@ echo
# Assignment
a=879
echo "The value of \"a\" is $a"
echo "The value of \"a\" is $a."
# Assignment using 'let'
let a=16+5
echo "The value of \"a\" is now $a"
echo "The value of \"a\" is now $a."
echo
# In a 'for' loop (really, a type of disguised assignment)
echo -n "The values of \"a\" in the loop are "
echo -n "Values of \"a\" in the loop are: "
for a in 7 8 9 11
do
echo -n "$a "
@ -28,7 +29,7 @@ echo
# In a 'read' statement (also a type of assignment)
echo -n "Enter \"a\" "
read a
echo "The value of \"a\" is now $a"
echo "The value of \"a\" is now $a."
echo

View File

@ -2,6 +2,7 @@
# Call this script with at least 10 parameters, for example
# ./scriptname 1 2 3 4 5 6 7 8 9 10
MINPARAMS=10
echo
@ -29,11 +30,17 @@ fi
# ...
if [ -n "${10}" ] # Parameters > $9 must be enclosed in {brackets}.
then
echo "Parameter #10 is ${10}"
fi
if [ $# -lt "$MINPARAMS" ]
then
echo "Give me at least $MINPARAMS command-line arguments!"
fi
echo
exit 0

View File

@ -30,8 +30,7 @@ case "$person" in
echo "revans@zzy.net"
echo "Business partner & old friend"
;;
# Note double semicolon to terminate
# each option.
# Note double semicolon to terminate each option.
"J" | "j" )
echo

View File

@ -11,16 +11,20 @@ echo "Command-line argument #1 = $1"
echo "Command-line argument #2 = $2"
echo "Command-line argument #3 = $3"
echo
set `uname -a` # Sets the positional parameters to the output
# of the command `uname -a`
echo $_ # unknown
# Flags set in script.
echo "Positional parameters after set \`uname -a\` :"
# $1, $2, $3, etc. reinitialized to result of `uname -a`
echo "Field #1 of 'uname -a' = $1"
echo "Field #2 of 'uname -a' = $2"
echo "Field #3 of 'uname -a' = $3"
echo ---
echo $_ # ---
echo
exit 0

View File

@ -1,11 +1,13 @@
#!/bin/bash
# burn-cd.sh
# Script to automate burning a CDR.
SPEED=2 # May use higher speed if your hardware supports it.
IMAGEFILE=cdimage.iso
CONTENTSFILE=contents
DEFAULTDIR=/opt # Make sure this directory exists.
# Script to automate burning a CDR.
DEFAULTDIR=/opt # This is the directory containing the data to be burned.
# Make sure it exists.
# Uses Joerg Schilling's "cdrecord" package.
# (http://www.fokus.gmd.de/nthp/employees/schilling/cdrecord.html)
@ -20,16 +22,19 @@ then
else
IMAGE_DIRECTORY=$1
fi
# Create a "table of contents" file.
ls -lRF $IMAGE_DIRECTORY > $IMAGE_DIRECTORY/$CONTENTSFILE
# The "l" option gives a "long" file listing.
# The "R" option makes the listing recursive.
# The "F" option marks the file types (directories get a trailing /).
echo "Creating table of contents."
# Create an image file preparatory to burning it onto the CDR.
mkisofs -r -o $IMAGFILE $IMAGE_DIRECTORY
echo "Creating ISO9660 file system image ($IMAGEFILE)."
# Burn the CDR.
cdrecord -v -isosize speed=$SPEED dev=0,0 $IMAGEFILE
echo "Burning the disk."
echo "Please be patient, this will take a while."

View File

@ -1,11 +1,14 @@
#!/bin/bash
# Using "seq"
echo
for a in `seq 80` # or for a in $( seq 80 )
# Same as for a in 1 2 3 4 5 ... 80 (saves much typing!).
# May also use 'jot' (if present on system).
do
echo -n "$a "
done
done # 1 2 3 4 5 ... 80
# Example of using the output of a command to generate
# the [list] in a "for" loop.
@ -17,8 +20,34 @@ COUNT=80 # Yes, 'seq' may also take a replaceable parameter.
for a in `seq $COUNT` # or for a in $( seq $COUNT )
do
echo -n "$a "
done
done # 1 2 3 4 5 ... 80
echo
echo; echo
BEGIN=75
END=80
for a in `seq $BEGIN $END`
# Giving "seq" two arguments starts the count at the first one,
#+ and continues until it reaches the second.
do
echo -n "$a "
done # 75 76 77 78 79 80
echo; echo
BEGIN=45
INTERVAL=5
END=80
for a in `seq $BEGIN $INTERVAL $END`
# Giving "seq" three arguments starts the count at the first one,
#+ uses the second for a step interval,
#+ and continues until it reaches the third.
do
echo -n "$a "
done # 45 50 55 60 65 70 75 80
echo; echo
exit 0

View File

@ -24,9 +24,9 @@ for i in /var/lock/subsys/*; do
# --> Match variable name, which, in this case, is the file name.
# --> This is the exact equivalent of subsys=`basename $i`.
# --> It gets it from the lock file name, and since if there
# --> is a lock file, that's proof the process has been running.
# --> See the "lockfile" entry, above.
# --> It gets it from the lock file name (if there is a lock file,
# -->+ that's proof the process has been running).
# --> See the "lockfile" entry, above.
# Bring the subsystem down.
@ -34,7 +34,7 @@ for i in /var/lock/subsys/*; do
/etc/rc.d/init.d/$subsys.init stop
else
/etc/rc.d/init.d/$subsys stop
# --> Suspend running jobs and daemons
# --> Suspend running jobs and daemons
# --> using the 'stop' shell builtin.
fi
done

View File

@ -3,17 +3,14 @@
# Backs up all files in current directory modified within last 24 hours
#+ in a "tarball" (tarred and gzipped file).
NOARGS=0
E_BADARGS=65
BACKUPFILE=backup
archive=${1:-$BACKUPFILE}
# If no backup-archive filename specified on command line,
#+ it will default to "backup.tar.gz."
if [ $# = $NOARGS ]
then
echo "Usage: `basename $0` filename"
exit $E_BADARGS
fi
tar cvf - `find . -mtime -1 -type f -print` > $1.tar
gzip $1.tar
tar cvf - `find . -mtime -1 -type f -print` > $archive.tar
gzip $archive.tar
echo "Directory $PWD backed up in archive file \"$archive.tar.gz\"."
# Stephane Chazelas points out that the above code will fail
@ -21,14 +18,14 @@ gzip $1.tar
#+ or if any filenames contain blank characters.
# He suggests the following alternatives:
# -------------------------------------------------------------
# find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$1.tar"
# -------------------------------------------------------------------
# find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"
# using the GNU version of "find".
# find . -mtime -1 -type f -exec tar rvf "$1.tar" '{}' \;
# portable to other UNIX flavors, but much slower.
# -------------------------------------------------------------
# find . -mtime -1 -type f -exec tar rvf "$archive.tar" '{}' \;
# portable to other UNIX flavors, but much slower.
# -------------------------------------------------------------------
exit 0

View File

@ -1,13 +1,22 @@
#!/bin/bash
# Functions and parameters
DEFAULT=default # Default param value.
func2 () {
if [ -z "$1" ] # Checks if parameter #1 is zero length.
if [ -z "$1" ] # Is parameter #1 zero length?
then
echo "-Parameter #1 is zero length.-" # Also if no parameter is passed.
echo "-Parameter #1 is zero length.-" # Or no parameter passed.
else
echo "-Param #1 is \"$1\".-"
fi
variable=${1-$DEFAULT} # What does
echo "variable = $variable" #+ parameter substitution show?
# ---------------------------
# It distinguishes between
#+ no param and a null param.
if [ "$2" ]
then
echo "-Parameter #2 is \"$2\".-"

View File

@ -18,12 +18,18 @@ then
fi
if [ -n "$1" ]
then
blocks=$1
else
blocks=$MINBLOCKS # Set to default of 40 blocks
fi # if nothing specified on command line.
blocks=${1:-$MINBLOCKS} # Set to default of 40 blocks,
#+ if nothing specified on command line.
# This is the equivalent of the command block below.
# --------------------------------------------------
# if [ -n "$1" ]
# then
# blocks=$1
# else
# blocks=$MINBLOCKS
# fi
# --------------------------------------------------
if [ "$blocks" -lt $MINBLOCKS ]
then

View File

@ -26,6 +26,7 @@ inum=`ls -i | grep "$1" | awk '{print $1}'`
# Every file has an inode, a record that hold its physical address info.
echo; echo -n "Are you absolutely sure you want to delete \"$1\" (y/n)? "
# The '-v' option to 'rm' also asks this.
read answer
case "$answer" in
[nN]) echo "Changed your mind, huh?"

View File

@ -1,11 +1,8 @@
#!/bin/bash
# Erratic behavior of the "$*" and "$@" internal Bash variables,
# depending on whether these are quoted or not.
# Word splitting and linefeeds handled inconsistently.
# This example script by Stephane Chazelas,
# and slightly modified by the document author.
# Erratic behavior of the "$*" and "$@" internal Bash variables,
#+ depending on whether they are quoted or not.
# Inconsistent handling of word splitting and linefeeds.
set -- "First one" "second" "third:one" "" "Fifth: :one"
@ -135,3 +132,6 @@ echo
# Try this script with ksh or zsh -y.
exit 0
# This example script by Stephane Chazelas,
# and slightly modified by the document author.

View File

@ -1,27 +1,45 @@
#!/bin/bash
# int-or-string.sh
# Integer or string?
# int-or-string.sh: Integer or string?
a=2334 # Integer.
let "a += 1"
echo "a = $a " # Integer, still.
echo
echo "a = $a " # a = 2335
echo # Integer, still.
b=${a/23/BB} # Transform into a string.
echo "b = $b" # BB35
b=${a/23/BB} # Substitute "BB" for "23".
# This transforms $b into a string.
echo "b = $b" # b = BB35
declare -i b # Declaring it an integer doesn't help.
echo "b = $b" # BB35, still.
echo "b = $b" # b = BB35
let "b += 1" # BB35 + 1 =
echo "b = $b" # 1
echo "b = $b" # b = 1
echo
c=BB34
echo "c = $c" # BB34
d=${c/BB/23} # Transform into an integer.
echo "d = $d" # 2334
echo "c = $c" # c = BB34
d=${c/BB/23} # Substitute "23" for "BB".
# This makes $d an integer.
echo "d = $d" # d = 2334
let "d += 1" # 2334 + 1 =
echo "d = $d" # 2335
echo "d = $d" # d = 2335
echo
# What about null variables?
e=""
echo "e = $e" # e =
let "e += 1" # Arithmetic operations allowed on a null variable?
echo "e = $e" # e = 1
echo # Null variable transformed into an integer.
# What about undeclared variables?
echo "f = $f" # f =
let "f += 1" # Arithmetic operations allowed?
echo "f = $f" # f = 1
echo # Undeclared variable transformed into an integer.
# Variables in Bash are essentially untyped.

View File

@ -1,5 +1,5 @@
#!/bin/bash
# Using "case" structure to filter a string.
# isalpha.sh: Using a "case" structure to filter a string.
SUCCESS=0
FAILURE=-1
@ -28,30 +28,78 @@ isalpha2 () # Tests whether *entire string* is alphabetic.
esac
}
isdigit () # Tests whether *entire string* is numerical.
{ # In other words, tests for integer variable.
[ $# -eq 1 ] || return $FAILURE
case $1 in
*[!0-9]*|"") return $FAILURE;;
*) return $SUCCESS;;
esac
}
check_var () # Front-end to isalpha().
check_var () # Front-end to isalpha ().
{
if isalpha "$@"
then
echo "$* = alpha"
echo "\"$*\" begins with an alpha character."
if isalpha2 "$@"
then # No point in testing if first char is non-alpha.
echo "\"$*\" contains only alpha characters."
else
echo "\"$*\" contains at least one non-alpha character."
fi
else
echo "$* = non-alpha" # Also "non-alpha" if no argument passed.
echo "\"$*\" begins with a non-alpha character."
# Also "non-alpha" if no argument passed.
fi
echo
}
digit_check () # Front-end to isdigit ().
{
if isdigit "$@"
then
echo "\"$*\" contains only digits [0 - 9]."
else
echo "\"$*\" has at least one non-digit character."
fi
echo
}
a=23skidoo
b=H3llo
c=-What?
d=`echo $b` # Command substitution.
d=What?
e=`echo $b` # Command substitution.
f=AbcDef
g=27234
h=27a34
i=27.34
check_var $a
check_var $b
check_var $c
check_var $d
check_var $e
check_var $f
check_var # No argument passed, so what happens?
#
digit_check $g
digit_check $h
digit_check $i
# Script improved by S.C.
exit 0 # Script improved by S.C.
exit 0
# Exercise:
# --------
# Write an 'isfloat ()' function that tests for floating point numbers.
# Hint: The function duplicates 'isdigit ()',
#+ but adds a test for a mandatory decimal point.

View File

@ -6,7 +6,7 @@ echo
for file in *
do
ls -l "$file" # Lists all files in $PWD (current directory).
# Recall that the wild card character "*" matches everything,
# Recall that the wild card character "*" matches every filename,
# however, in "globbing", it doesn't match dot-files.
# If the pattern matches no file, it is expanded to itself.

View File

@ -5,7 +5,7 @@
string=abcdA01
echo "len($string)" | m4 # 7
echo "substr($string,4)" | m4 # A01
echo "regexp($string,[0-1][0-1],\&amp;Z)" | m4 # 01Z
echo "regexp($string,[0-1][0-1],\&amp;Z)" | m4 # 01Z
# Arithmetic
echo "incr(22)" | m4 # 23

View File

@ -40,6 +40,6 @@ s/ *//
#+ extolling a 164K Windows utility with similar functionality.
#
# An nice set of text processing utilities and an efficient
#+ scripting language makes unnecessary bloated executables.
#+ scripting language provide an alternative to bloated executables.
exit 0

View File

@ -1,14 +1,14 @@
#!/bin/bash
# manview.sh: Formats the source of a man page for viewing.
# This is useful when writing man page source and you want to
# look at the intermediate results on the fly while working on it.
# This is useful when writing man page source and you want to
#+ look at the intermediate results on the fly while working on it.
E_WRONGARGS=65
if [ -z "$1" ]
then
echo "Usage: `basename $0` [filename]"
echo "Usage: `basename $0` filename"
exit $E_WRONGARGS
fi

View File

@ -1,24 +1,26 @@
#!/bin/bash
# numbers.sh: Representation of numbers.
# numbers.sh: Representation of numbers in different bases.
# Decimal
# Decimal: the default
let "dec = 32"
echo "decimal number = $dec" # 32
# Nothing out of the ordinary here.
# Octal: numbers preceded by '0' (zero)
let "oct = 071"
echo "octal number = $oct" # 57
let "oct = 032"
echo "octal number = $oct" # 26
# Expresses result in decimal.
# --------- ------ -- -------
# Hexadecimal: numbers preceded by '0x' or '0X'
let "hex = 0x7a"
echo "hexadecimal number = $hex" # 122
let "hex = 0x32"
echo "hexadecimal number = $hex" # 50
# Expresses result in decimal.
# Other bases: BASE#NUMBER
# BASE between 2 and 64.
# NUMBER must use symbols within the BASE range, see below.
let "bin = 2#111100111001101"
echo "binary number = $bin" # 31181
@ -38,13 +40,13 @@ echo $((36#zz)) $((2#10101010)) $((16#AF16)) $((53#1aA))
# 1295 170 44822 3375
# Important note:
# Important note:
# --------------
# Using a digit out of range of the specified base notation
#+ will give an error message.
let "bad_oct = 081"
# numbers.sh: let: oct = 081: value too great for base (error token is "081")
# Octal numbers use only digits in the range of 0 - 7.
# Octal numbers use only digits in the range 0 - 7.
exit 0
# Thanks, Rich Bartell and Stephane Chazelas, for clarification.
exit 0 # Thanks, Rich Bartell and Stephane Chazelas, for clarification.

View File

@ -1,12 +1,13 @@
#!/bin/bash
# rot13.sh: Classic rot13 algorithm, encryption that might fool a 3-year old.
# rot13.sh: Classic rot13 algorithm,
# encryption that might fool a 3-year old.
# Usage: ./rot13.sh filename
# or ./rot13.sh &lt;filename
# or ./rot13.sh and supply keyboard input (stdin)
cat "$@" | tr 'a-zA-Z' 'n-za-mN-ZA-M' # "a" goes to "n", "b" to "o", etc.
# The 'cat "$@"' construction
# permits getting input either from stdin or from files.
# The 'cat "$@"' construction
#+ permits getting input either from stdin or from files.
exit 0

View File

@ -1,13 +1,13 @@
#!/bin/bash
ENDLESS_LOOP=1
TIME_LIMIT=10
INTERVAL=1
echo
echo "Hit Control-C to exit this script."
echo "Hit Control-C to exit before $TIME_LIMIT seconds."
echo
while [ $ENDLESS_LOOP ]
while [ "$SECONDS" -le "$TIME_LIMIT" ]
do
if [ "$SECONDS" -eq 1 ]
then
@ -17,8 +17,11 @@ do
fi
echo "This script has been running $SECONDS $units."
# On a slow or overburdened machine, the script may skip a count
#+ every once in a while.
sleep $INTERVAL
done
echo -e "\a" # Beep!
exit 0

View File

@ -8,3 +8,13 @@ echo "This line will not echo."
# Instead, the shell sends a "Terminated" message to stdout.
exit 0
# After this script terminates prematurely,
#+ what exit status does it return?
#
# sh self-destruct.sh
# echo $?
# 143
#
# 143 = 128 + 15
# TERM signal

View File

@ -1,5 +1,6 @@
#!/bin/bash
# stupid-script-tricks.sh: Don't try this at home, folks.
# From "Stupid Script Tricks," Volume I.
dangerous_variable=`cat /boot/vmlinuz` # The compressed Linux kernel itself.

View File

@ -1,14 +1,21 @@
#!/bin/bash
# symlinks.sh: Lists symbolic links in a directory.
ARGS=1 # Expect one command-line argument.
if [ $# -ne "$ARGS" ] # If not 1 arg...
then
directory=`pwd` # current working directory
else
directory=$1
fi
directory=${1-`pwd`}
# Defaults to current working directory,
#+ if not otherwise specified.
# Equivalent to code block below.
# ----------------------------------------------------------
# ARGS=1 # Expect one command-line argument.
#
# if [ $# -ne "$ARGS" ] # If not 1 arg...
# then
# directory=`pwd` # current working directory
# else
# directory=$1
# fi
# ----------------------------------------------------------
echo "symbolic links in directory \"$directory\""

View File

@ -1,22 +1,20 @@
#!/bin/bash
# symlinks.sh: Lists symbolic links in a directory.
ARGS=1 # Expect one command-line argument.
OUTFILE=symlinks.list # save file
OUTFILE=symlinks.list # save file
if [ $# -ne "$ARGS" ] # If not 1 arg...
then
directory=`pwd` # current working directory
else
directory=$1
fi
directory=${1-`pwd`}
# Defaults to current working directory,
#+ if not otherwise specified.
echo "symbolic links in directory \"$directory\""
for file in "$( find $directory -type l )" # -type l = symbolic links
echo "symbolic links in directory \"$directory\"" > "$OUTFILE"
echo "---------------------------" >> "$OUTFILE"
for file in "$( find $directory -type l )" # -type l = symbolic links
do
echo "$file"
done | sort > "$OUTFILE" # stdout of loop
# ^^^^^^^^^^^^ redirected to save file.
done | sort >> "$OUTFILE" # stdout of loop
# ^^^^^^^^^^^^^ redirected to save file.
exit 0