Linux15_Shell实例(翻译_1)

转自

http://www.intuitive.com/wicked/wicked-cool-shell-script-library.shtml

 

先抄下来,后面有空慢慢加中文注释。

inpath.sh

#!/bin/sh
# inpath - verify that a specified programis either valid as-is,
#  or can be found in the PATH directory list.
 
in_path()
{
  #given a command and the PATH, try to find the command. Returns
  # 0if found and executable, 1 if not. Note that this temporarily modifies
  #the IFS (input field seperator), but restores it upon completion.
 
 cmd=$1        path=$2         retval=1
 oldIFS=$IFS   IFS=":"
 
  fordirectory in $path
  do
   if [ -x $directory/$cmd ] ; then
     retval=0      # if we're here, wefound $cmd in $directory
   fi
 done
 IFS=$oldIFS
 return $retval
}
 
checkForCmdInPath()
{
 var=$1
 
  #The variable slicing notation in the following conditional
  #needs some explanation: ${var#expr} returns everything after
  #the match for 'expr' in the variable value (if any), and
  #${var%expr} returns everything that doesn't match (in this
  #case just the very first character. You can also do this in
  #Bash with ${var:0:1} and you could use cut too: cut -c1
 
  if[ "$var" != "" ] ; then
    if [ "${var%${var#?}}" ="/" ] ; then
     if [ ! -x $var ] ; then
       return 1
     fi
   elif ! in_path $var $PATH ; then
     return 2
   fi
  fi
}
 
if [ $# -ne 1 ] ; then
 echo"Usage: $0 command" >&2 ; exit 1
fi
 
checkForCmdInPath "$1"
case $? in
  0 )echo "$1 found in PATH"                            ;;
  1 )echo "$1 not found or not executable"  ;;
  2 )echo "$1 not found in PATH"            ;;
esac
 
exit 0

 

validalnum.sh

#!/bin/sh
# validalAlphaNum - Ensures that input onlyconsists of alphabetical
#              and numeric characters.
 
validAlphaNum()
{
  #validate arg: returns 0 if all upper+lower+digits, 1 otherwise
 
  #Remove all unacceptable chars
 compressed="$(echo $1 | sed -e 's/[^[:alnum:]]//g')"
 
  if[ "$compressed" != "$input" ] ; then
   return 1
  else
   return 0
  fi
}
 
# Sample usage of this function in a script
 
echo -n "Enter input: "
read input
 
if ! validAlphaNum "$input" ;then
 echo "Your input must consist of only letters and numbers.">&2
 exit 1
else
 echo "Input is valid."
fi
 
exit 0

 

normdate.sh

#!/bin/sh
# normdate - Normalizes month field in datespecification
#   to three letters, first letter capitalized. A helper
#   function for hack #7, validdate. Exits w/ zero if no error.
 
monthnoToName()
{
  #sets the variable 'month' to the appropriate value
 case $1 in
    1) month="Jan"    ;;  2 ) month="Feb"    ;;
    3) month="Mar"    ;;  4 ) month="Apr"    ;;
    5) month="May"    ;;  6 ) month="Jun"    ;;
    7) month="Jul"    ;;  8 ) month="Aug"    ;;
    9) month="Sep"    ;;  10) month="Oct"    ;;
   11) month="Nov"   ;;  12) month="Dec"    ;;
    *) echo "$0: Unknown numeric month value $1" >&2; exit 1
  esac
  return 0
}
 
## Begin main script
 
if [ $# -eq 1 ] ; then  # try to compensate for / or - formats
  set-- $(echo $1 | sed 's/[\/\-]/ /g')
fi
 
if [ $# -ne 3 ] ; then
 echo "Usage: $0 month day year" >&2
 echo "Typical input formats are August 3 1962 and 8 3 2002">&2
 exit 1
fi
 
if [ $3 -lt 99 ] ; then
 echo"$0: expected four-digit year value." >&2; exit 1
fi
 
if [ -z $(echo $1|sed 's/[[:digit:]]//g')]; then
 monthnoToName $1
else
  #normalize to first three letters, first upper, rest lowercase
 month="$(echo $1|cut -c1|tr '[:lower:]' '[:upper:]')"
 month="$month$(echo $1|cut -c2-3 | tr '[:upper:]' '[:lower:]')"
fi
 
echo $month $2 $3
 
exit 0

nicenumber.sh

#!/bin/sh
 
# nicenumber - given a number, show it withcomma separated values
#   expects DD and TD to be instantiated. instantiates nicenum
#   or, if a second arg is specified, the output is echoed to stdout
 
nicenumber()
{
  #Note that we use the '.' as the decimal separator for parsing
  #the INPUT value to this script. The output value is as specified
  #by the user with the -d flag, if different from a '.'
  
 integer=$(echo $1 | cut -d. -f1)            #left of the decimal
 decimal=$(echo $1 | cut -d. -f2)           #right of the decimal
 
  if[ $decimal != $1 ]; then
    #there's a fractional part, let's include it.
   result="${DD:="."}$decimal"
  fi
 
 thousands=$integer
 
 while [ $thousands -gt 999 ]; do
   remainder=$(($thousands % 1000))        #three least significant digits
 
   while [ ${#remainder} -lt 3 ] ; do      #force leading zeroes as needed
     remainder="0$remainder"
   done
   
   thousands=$(($thousands / 1000)) #to left of remainder, if any
   result="${TD:=","}${remainder}${result}"       # builds right-to-left
 done
 
 nicenum="${thousands}${result}"
  if[ ! -z $2 ] ; then
   echo $nicenum
  fi
}
 
DD="."     # decimal point delimiter, between integer & fractionalvalue
TD=","      # thousands delimiter, separates every three digits
 
while getopts "d:t:" opt; do
 case $opt in
    d) DD="$OPTARG" ;;
    t) TD="$OPTARG"   ;;
 esac
done
 
shift $(($OPTIND - 1))
 
if [ $# -eq 0 ] ; then
  cat<< "EOF" >&2
Usage: $(basename $0) [-d c] [-t c] numericvalue
      -d specifies the decimal point delimiter (default '.')
      -t specifies the thousands delimiter (default ',')
EOF
 exit 1
fi
 
nicenumber $1 1               # second arg forces this to 'echo' output
 
exit 0

validint.sh

#!/bin/sh
# validint - validate integer input, allownegative ints too
 
validint()
{
  #validate first field. Optionally test against min value $2 and/or
  #max value $3: if you'd rather skip these tests, send "" as values.
  #returns 1 for error, 0 for success.
 
 number="$1";          min="$2";            max="$3"
 
  if[ -z $number ] ; then
   echo "You didn't enter anything. Unacceptable." >&2 ;return 1
  fi
 
  if[ "${number%${number#?}}" = "-" ] ; then        # first char '-' ?
   testvalue="${number#?}"      #all but first character
 else
   testvalue="$number"
  fi
 
 nodigits="$(echo $testvalue | sed 's/[[:digit:]]//g')"
 
  if[ ! -z $nodigits ] ; then
   echo "Invalid number format! Only digits, no commas, spaces,etc." >&2
   return 1
  fi
 
  if[ ! -z $min ] ; then
   if [ "$number" -lt "$min" ] ; then
      echo "Your value is too small: smallest acceptable value is$min" >&2
      return 1
   fi
  fi
  if[ ! -z $max ] ; then
    if [ "$number" -gt "$max" ] ; then
      echo "Your value is too big: largest acceptable value is $max">&2
      return 1
    fi
  fi
 return 0
}
 
# uncomment these lines to test, but bewarethat it'll break Hack #6
# because Hack #6 wants to source this fileto get the validint()
# function. :-)
 
# if validint "$1" "$2""$3" ; then
#  echo "That input is a valid integer value within yourconstraints"
# fi


validfloat.sh

#!/bin/sh
 
# validfloat - test whether a number is avalid floating point value.
#   Note that this cannot accept scientific (1.304e5) notation.
 
# To test whether an entered value is avalid floating point number, we
# need to split the value at the decimalpoint, then test the first part
# to see if it's a valid integer, then thesecond part to see if it's a
# valid >=0 integer, so -30.5 is valid,but -30.-8 isn't.
 
. 005-validint.sh                 # source the validint function
 
validfloat()
{
 fvalue="$1"
 
  if[ ! -z $(echo $fvalue | sed 's/[^.]//g') ] ; then
 
   decimalPart="$(echo $fvalue | cut -d. -f1)"
   fractionalPart="$(echo $fvalue | cut -d. -f2)"
 
   if [ ! -z $decimalPart ] ; then
     if ! validint "$decimalPart" "" "" ; then
       return 1
     fi
   fi
 
   if [ "${fractionalPart%${fractionalPart#?}}" = "-" ]; then
     echo "Invalid floating point number: '-' not allowed \
         afterdecimal point" >&2
     return 1
   fi
   if [ "$fractionalPart" != "" ] ; then
     if ! validint "$fractionalPart" "0" "" ;then
       return 1
     fi
   fi
 
   if [ "$decimalPart" = "-" -o -z $decimalPart ] ;then
     if [ -z $fractionalPart ] ; then
       echo "Invalid floating point format." >&2 ; return 1
     fi
   fi
 
 else
   if [ "$fvalue" = "-" ] ; then
     echo "Invalid floating point format." >&2 ; return 1
   fi
 
   if ! validint "$fvalue" "" "" ; then
     return 1
   fi
  fi
 
 return 0
}
 
if validfloat $1 ; then
 echo "$1 is a valid floating point value"
fi
 
exit 0


valid-date.sh

#!/bin/sh
# valid-date - validate date, taking intoaccount leap year rules
 
normdate="./003-normdate.sh"     # hack #3 for normalizing month name
 
exceedsDaysInMonth()
{
  #given a month name, return 0 if the specified day value is
  #less than or equal to the max days in the month, 1 otherwise
 
 case $(echo $1|tr '[:upper:]' '[:lower:]') in
   jan* ) days=31    ;;  feb* ) days=28    ;;
   mar* ) days=31    ;;  apr* ) days=30    ;;
   may* ) days=31    ;;  jun* ) days=30    ;;
   jul* ) days=31    ;;  aug* ) days=31    ;;
   sep* ) days=30    ;;  oct* ) days=31    ;;
   nov* ) days=30    ;;  dec* ) days=31    ;;
    *) echo "$0: Unknown month name $1" >&2; exit 1
  esac
  
   if[ $2 -lt 1 -o $2 -gt $days ] ; then
    return 1
  else
    return 0 # all is well
   fi
}
 
isLeapYear()
{   
  #this function returns 0 if a leap year, 1 otherwise
  #The formula for checking whether a year is a leap year is:
  #1. years divisible by four are leap years, unless..
  #2. years also divisible by 100 are not leap years, except...
  #3. years divisible by 400 are leap years
 
 year=$1
  if[ "$((year % 4))" -ne 0 ] ; then
   return 1 # nope, not a leap year
 elif [ "$((year % 400))" -eq 0 ] ; then
   return 0 # yes, it's a leap year
 elif [ "$((year % 100))" -eq 0 ] ; then
   return 1
 else
   return 0
  fi
}
 
## Begin main script
 
if [ $# -ne 3 ] ; then
 echo "Usage: $0 month day year" >&2
 echo "Typical input formats are August 3 1962 and 8 3 2002">&2
 exit 1
fi
 
# normalize date and split back outreturned values
 
newdate="$($normdate"$@")"
 
if [ $? -eq 1 ] ; then
 exit 1    # error condition alreadyreported by normdate
fi
 
month="$(echo $newdate | cut -d\  -f1)"
 day="$(echo $newdate | cut -d\ -f2)"
 year="$(echo $newdate | cut -d\  -f3)"
 
# Now that we have a normalized date, let'scheck to see if the
# day value is logical
 
if ! exceedsDaysInMonth $month"$2" ; then
  if[ "$month" = "Feb" -a $2 -eq 29 ] ; then
   if ! isLeapYear $3 ; then
     echo "$0: $3 is not a leap year, so Feb doesn't have 29 days">&2
     exit 1
   fi
 else
   echo "$0: bad day value: $month doesn't have $2 days">&2
   exit 1
  fi
fi
 
echo "Valid date: $newdate"
 
exit 0


echon.sh

#!/bin/sh
 
# echon - a script to emulate the -n flagfunctionality with 'echo'
#  for Unix systems that don't have that available.
 
echon()
{
 echo "$*" | tr -d '\n'
}
 
echon "this is a test: "
read answer
 
echon this is a test too " "
read answer2


scriptbc.sh

#!/bin/sh
 
# echon - a script to emulate the -n flagfunctionality with 'echo'
#  for Unix systems that don't have that available.
 
echon()
{
 echo "$*" | tr -d '\n'
}
 
echon "this is a test: "
read answer
 
echon this is a test too " "
read answer2

filelock.sh

#!/bin/sh
 
# echon - a script to emulate the -n flagfunctionality with 'echo'
#  for Unix systems that don't have that available.
 
echon()
{
 echo "$*" | tr -d '\n'
}
 
echon "this is a test: "
read answer
 
echon this is a test too " "
read answer2

colors.sh

#!/bin/sh
 
# ANSI Color -- use these variables toeasily have different color
#   and format output. Make sure to output the reset sequence after
#   colors (f = foreground, b = background), and use the 'off'
#   feature for anything you turn on.
 
initializeANSI()
{
 esc=""
 
 blackf="${esc}[30m";  redf="${esc}[31m";   greenf="${esc}[32m"
 yellowf="${esc}[33m"  bluef="${esc}[34m";  purplef="${esc}[35m"
 cyanf="${esc}[36m";   whitef="${esc}[37m"
 
 blackb="${esc}[40m";  redb="${esc}[41m";   greenb="${esc}[42m"
 yellowb="${esc}[43m"  blueb="${esc}[44m";  purpleb="${esc}[45m"
 cyanb="${esc}[46m";   whiteb="${esc}[47m"
 
 boldon="${esc}[1m";   boldoff="${esc}[22m"
 italicson="${esc}[3m"; italicsoff="${esc}[23m"
 ulon="${esc}[4m";     uloff="${esc}[24m"
 invon="${esc}[7m";    invoff="${esc}[27m"
 
 reset="${esc}[0m"
}
 
# note in this first use that switchingcolors doesn't require a reset
# first - the new color overrides the oldone.
 
initializeANSI
 
cat << EOF
${yellowf}This is a phrase in yellow${redb}and red${reset}
${boldon}This is bold${ulon} this isitalics${reset} bye bye
${italicson}This is italics${italicsoff}and this is not
${ulon}This is ul${uloff} and this is not
${invon}This is inv${invoff} and this isnot
${yellowf}${redb}WarningI${yellowb}${redf}Warning II${reset}
EOF


library-test.sh

#!/bin/sh
 
# Script to demonstrate use of the shellfunction library
 
. 012-library.sh
 
initializeANSI
 
echon "First off, do you have echo inyour path? (1=yes, 2=no) "
read answer
while ! validint $answer 1 2 ; do
 echon "${boldon}Try again${boldoff}. Do you have echo "
 echon "in your path? (1=yes, 2=no) "
 read answer
done
 
if ! checkForCmdInPath "echo" ;then
 echo "Nope, can't find the echo command."
else
 echo "The echo command is in the PATH."
fi
 
echo ""
echon "Enter a year you think might bea leap year: "
read year
 
while ! validint $year 1 9999 ; do
 echon "Please enter a year in the ${boldon}correct${boldoff}format: "
 read year
done
 
if isLeapYear $year ; then
 echo "${greenf}You're right! $year was a leap year.${reset}"
else
 echo "${redf}Nope, that's not a leap year.${reset}"
fi
 
exit 0


library.sh

#!/bin/sh
 
# inpath - verify that a specified programis either valid as-is,
#  or can be found in the PATH directory list.
 
in_path()
{
  #given a command and the PATH, try to find the command. Returns
  # 0if found and executable, 1 if not. Note that this temporarily modifies
  #the the IFS (input field seperator), but restores it upon completion.
  #return variable 'directory' contains the directory where the
  #command was found.
 
 cmd=$1        path=$2         retval=1
 oldIFS=$IFS   IFS=":"
 
  fordirectory in $path
  do
   if [ -x $directory/$cmd ] ; then
     retval=0      # if we're here, wefound $cmd in $directory
    fi
 done
 IFS=$oldIFS
 return $retval
}
 
checkForCmdInPath()
{
 var=$1
 
  #The variable slicing notation in the following conditional
  #needs some explanation: ${var#expr} returns everything after
  #the match for 'expr' in the variable value (if any), and
  #${var%expr} returns everything that doesn't match (in this
  #case just the very first character. You can also do this in
  #Bash with ${var:0:1} and you could use cut too: cut -c1
 
  if[ "$var" != "" ] ; then
   if [ "${var%${var#?}}" = "/" ] ; then
     if [ ! -x $var ] ; then
       return 1
     fi
   elif ! in_path $var $PATH ; then
     return 2
   fi
  fi
 return 0
}
 
# cnvalidate - Ensures that input onlyconsists of alphabetical
#              and numeric characters.
 
cnvalidate()
{
  #validate arg: returns 0 if all upper+lower+digits, 1 otherwise
 
  #Remove all unacceptable chars
 compressed="$(echo $1 | sed -e 's/[^[:alnum:]]//g')"
 
  if[ "$compressed" != "$input" ] ; then
   return 1
 else
   return 0
  fi
}
 
monthnoToName()
{
  #sets the variable 'month' to the appropriate value
 case $1 in
    1) month="Jan"    ;;  2 ) month="Feb"    ;;
    3) month="Mar"    ;;  4 ) month="Apr"    ;;
    5) month="May"    ;;  6 ) month="Jun"    ;;
    7) month="Jul"    ;;  8 ) month="Aug"    ;;
    9) month="Sep"    ;;  10) month="Oct"    ;;
   11) month="Nov"   ;;  12) month="Dec"    ;;
    *) echo "$0: Unknown numeric month value $1" >&2; exit 1
  esac
  return 0
}
 
# nicenumber - given a number, show it withcomma separated values
#   expects DD and TD to be instantiated. instantiates nicenum
#   if arg2 is specified, this function echoes output, rather than
#   sending it back as a variable
 
nicenumber()
{
  #Note that we use the '.' as the decimal separator for parsing
  #the INPUT value to this script. The output value is as specified
  #by the user with the -d flag, if different from a '.'
 
 integer=$(echo $1 | cut -d. -f1)            #left of the decimal
 decimal=$(echo $1 | cut -d. -f2)           #right of the decimal
 
  if[ $decimal != $1 ]; then
    #there's a fractional part, let's include it.
   result="${DD:="."}$decimal"
  fi
 
 thousands=$integer
 
 while [ $thousands -gt 999 ]; do
   remainder=$(($thousands % 1000))        #three least significant digits
  
   while [ ${#remainder} -lt 3 ] ; do      #force leading zeroes as needed
     remainder="0$remainder"
   done
 
   thousands=$(($thousands / 1000)) #to left of remainder, if any
   result="${TD:=","}${remainder}${result}"       # builds right-to-left
  done
 
 nicenum="${thousands}${result}"
 
  if[ ! -z $2 ] ; then
    echo $nicenum
  fi
}
 
# validint - validate integer input, allownegative ints too
 
validint()
{
  #validate first field. Optionally test against min value $2 and/or
  #max value $3: if you'd rather skip these tests, send "" as values.
  #returns 1 for error, 0 for success
 
 number="$1";          min="$2";            max="$3"
 
  if[ -z "$number" ] ; then
   echo "You didn't enter anything. Unacceptable." >&2 ;return 1
  fi
 
  if[ "${number%${number#?}}" = "-" ] ; then        # first char '-' ?
   testvalue="${number#?}"      #all but first character
 else
   testvalue="$number"
  fi
 
 nodigits="$(echo $testvalue | sed 's/[[:digit:]]//g')"
 
  if[ ! -z "$nodigits" ] ; then
   echo "Invalid number format! Only digits, no commas, spaces,etc." >&2
   return 1
  fi
 
  if[ ! -z "$min" ] ; then
   if [ "$number" -lt "$min" ] ; then
      echo "Your value is too small: smallest acceptable value is$min" >&2
      return 1
   fi
  fi
  if[ ! -z "$max" ] ; then
    if [ "$number" -gt "$max" ] ; then
      echo "Your value is too big: largest acceptable value is $max">&2
      return 1
    fi
  fi
 return 0
}
 
# validfloat - test whether a number is avalid floating point value.
#   Note that this cannot accept scientific (1.304e5) notation.
 
# To test whether an entered value is avalid floating point number, we
# need to split the value at the decimalpoint, then test the first part
# to see if it's a valid integer, then the secondpart to see if it's a
# valid >=0 integer, so -30.5 is valid,but -30.-8 isn't.  Returns 0 on
# success, 1 on failure.
 
validfloat()
{
 fvalue="$1"
 
  if[ ! -z "$(echo $fvalue | sed 's/[^.]//g')" ] ; then
 
   decimalPart="$(echo $fvalue | cut -d. -f1)"
   fractionalPart="$(echo $fvalue | cut -d. -f2)"
 
   if [ ! -z "$decimalPart" ] ; then
     if ! validint "$decimalPart" "" "" ; then
       return 1
     fi
   fi
 
   if [ "${fractionalPart%${fractionalPart#?}}" = "-" ]; then
      echo "Invalid floating point number:'-' not allowed \
       after decimal point" >&2
     return 1
   fi
   if [ "$fractionalPart" != "" ] ; then
     if ! validint "$fractionalPart" "0" "" ;then
       return 1
     fi
   fi
 
   if [ "$decimalPart" = "-" -o -z"$decimalPart" ] ; then
     if [ -z "$fractionalPart" ] ; then
       echo "Invalid floating point format." >&2 ; return 1
     fi
   fi
 
 else
   if [ "$fvalue" = "-" ] ; then
     echo "Invalid floating point format." >&2 ; return 1
   fi
 
   if ! validint "$fvalue" "" "" ; then
     return 1
   fi
  fi
 
 return 0
}
 
exceedsDaysInMonth()
{
  #given a month name, return 0 if the specified day value is
  #less than or equal to the max days in the month, 1 otherwise
 
 case $(echo $1|tr '[:upper:]' '[:lower:]') in
   jan* ) days=31    ;;  feb* ) days=28    ;;
   mar* ) days=31    ;;  apr* ) days=30    ;;
   may* ) days=31    ;;  jun* ) days=30    ;;
   jul* ) days=31    ;;  aug* ) days=31    ;;
   sep* ) days=30    ;; oct* ) days=31    ;;
   nov* ) days=30    ;;  dec* ) days=31    ;;
    *) echo "$0: Unknown month name $1" >&2; exit 1
  esac
  
   if[ $2 -lt 1 -o $2 -gt $days ] ; then
    return 1
  else
    return 0 # all is well
   fi
}
 
isLeapYear()
{   
  #this function returns 0 if a leap year, 1 otherwise
  #The formula for checking whether a year is a leap year is:
  #1. years divisible by four are leap years, unless..
  #2. years also divisible by 100 are not leap years, except...
  #3. years divisible by 400 are leap years
 
 year=$1
  if[ "$((year % 4))" -ne 0 ] ; then
   return 1 # nope, not a leap year
 elif [ "$((year % 400))" -eq 0 ] ; then
   return 0 # yes, it's a leap year
 elif [ "$((year % 100))" -eq 0 ] ; then
   return 1
 else
   return 0
  fi
}
 
validdate()
{
  #expects three values, month, day and year. Returns 0 if success.
 
 newdate="$(normdate "$@")"
 
  if[ $? -eq 1 ] ; then
   exit 1        # error conditionalready reported by normdate
  fi
 
 month="$(echo $newdate | cut -d\ -f1)"
   day="$(echo $newdate | cut -d\ -f2)"
  year="$(echo $newdate | cut -d\ -f3)"
 
  #Now that we have a normalized date, let's check to see if the
  #day value is logical
 
  if! exceedsDaysInMonth $month "$2" ; then
   if [ "$month" = "Feb" -a $2 -eq 29 ] ; then
     if ! isLeapYear $3 ; then
       echo "$0: $3 is not a leap year, so Feb doesn't have 29 days">&2
       exit 1
     fi
   else
     echo "$0: bad day value: $month doesn't have $2 days">&2
     exit 1
   fi
  fi
 return 0
}
 
echon()
{
 echo "$*" | tr -d '\n'
}
 
initializeANSI()
{
 esc=""
 
 blackf="${esc}[30m";  redf="${esc}[31m";   greenf="${esc}[32m"
 yellowf="${esc}[33m"  bluef="${esc}[34m";  purplef="${esc}[35m"
 cyanf="${esc}[36m";   whitef="${esc}[37m"
 
 blackb="${esc}[40m";  redb="${esc}[41m";   greenb="${esc}[42m"
 yellowb="${esc}[43m"  blueb="${esc}[44m";  purpleb="${esc}[45m"
 cyanb="${esc}[46m";   whiteb="${esc}[47m"
 
 boldon="${esc}[1m";   boldoff="${esc}[22m"
 italicson="${esc}[3m"; italicsoff="${esc}[23m"
 ulon="${esc}[4m";     uloff="${esc}[24m"
 invon="${esc}[7m";    invoff="${esc}[27m"
 
 reset="${esc}[0m"
}


hilow.sh

#!/bin/sh
# hilow - a simple number guessing game
 
biggest=100                             # maximum numberpossible
guess=0                                 # guessed byplayer
guesses=0                               # number ofguesses made
number=$(( $$ % $biggest ))             # random number, 1 .. $biggest
 
while [ $guess -ne $number ] ; do
 echo -n "Guess? " ; read guess
  if[ "$guess" -lt $number ] ; then
   echo "... bigger!"
 elif [ "$guess" -gt $number ] ; then
   echo "... smaller!"
  fi
 guesses=$(( $guesses + 1 ))
done
 
echo "Right!! Guessed $number in$guesses guesses."
 
exit 0


nfmt.sh

#!/bin/sh
 
# nfmt - A version of fmt, using nroff.Adds two useful flags: -w X for
# line width and -h to enable hyphenationfor better fills.
 
while getopts "hw:" opt; do
 case $opt in
    h) hyph=1                 ;;
    w) width="$OPTARG"    ;;
  esac
done
shift $(($OPTIND - 1))
 
nroff << EOF
.ll ${width:-72}
.na
.hy ${hyph:-0}
.pl 1
$(cat "$@")
EOF
 
exit 0


newrm.sh

#!/bin/sh
 
# newrm - a replacement for the existing rmcommand that allows a
#  rudimentary unremove capability through utilizing a newly created
#  directory in the user's home directory. It can handle directories
#  of content as well as individual files, and if the user specifies
#  the -f flag, files are NOT archived, but removed.
 
# Big Important Warning: you'll want a cronjob or similar to keep the
#  individual trash directories tamed, otherwise nothing will ever
#  actually be deleted on the system and you'll run out of disk space!
 
 mydir="$HOME/.deleted-files"
realrm="/bin/rm "
 copy="/bin/cp -R"
 
if [ $# -eq 0 ] ; then  # let 'rm' ouptut the usage error
 exec $realrm        # our shelldies and is replaced by /bin/rm
fi
 
# parse all options looking for '-f'
 
flags=""
 
while getopts "dfiPRrvW" opt
do
 case $opt in
    f) exec $realrm "$@"     ;;  # exec lets us exit this script directly.
    *) flags="$flags -$opt"  ;;  # other flags are for 'rm', not us
 esac
done
shift $(( $OPTIND - 1 ))
 
# make sure that the $mydir exists
 
if [ ! -d $mydir ] ; then
  if[ ! -w $HOME ] ; then
    echo"$0 failed: can't create $mydir in $HOME" >&2
   exit 1
  fi
 mkdir $mydir
 chmod 700 $mydir       # a littlebit of privacy, please
fi
 
for arg
do
 newname="$mydir/$(date "+%S.%M.%H.%d.%m").$(basename"$arg")"
  if[ -f "$arg" ] ; then
   $copy "$arg" "$newname"
 elif [ -d "$arg" ] ; then
   $copy "$arg" "$newname"
  fi
done
 
exec $realrm $flags "$@"       # our shell is replaced by realrm

unrm.sh

#!/bin/sh
 
# unrm - search the deleted files archivefor the specified file. If
#  there is more than one match, show a list ordered by timestamp, and
#  let the user specify which they want restored.
 
# Big Important Warning: you'll want a cronjob or similar to keep the
#  individual trash directories tamed, otherwise nothing will ever
#  actually be deleted on the system and you'll run out of disk space!
 
mydir="$HOME/.deleted-files"
realrm="/bin/rm"
move="/bin/mv"
 
dest=$(pwd)
 
if [ ! -d $mydir ] ; then
 echo "$0: No deleted files directory: nothing to unrm">&2 ; exit 1
fi
 
cd $mydir
 
if [ $# -eq 0 ] ; then # no args, just showlisting
 echo "Contents of your deleted files archive (sorted bydate):"
#  ls-FC | sed -e 's/[[:digit:]][[:digit:]]\.//g' -e 's/^/  /'
  ls-FC | sed -e 's/\([[:digit:]][[:digit:]]\.\)\{5\}//g' \
   -e 's/^/  /'
  exit0
fi
 
# Otherwise we must have a pattern to workwith. Let's see if the
# user-specified pattern matches more thanone file or directory
# in the archive.
 
matches="$(ls *"$1" 2>/dev/null | wc -l)"
 
if [ $matches -eq 0 ] ; then
 echo "No match for \"$1\" in the deleted filearchive." >&2
 exit 1
fi
 
if [ $matches -gt 1 ] ; then
 echo "More than one file or directory match in the archive:"
 index=1
  forname in $(ls -td *"$1")
  do
   datetime="$(echo $name | cut -c1-14| \
      awk -F. '{ print $5"/"$4" at"$3":"$2":"$1 }')"
   if [ -d $name ] ; then
     size="$(ls $name | wc -l | sed 's/[^0-9]//g')"
     echo " $index)   $1  (contents = ${size} items, deleted =$datetime)"
   else
     size="$(ls -sdk1 $name | awk '{print $1}')"
     echo " $index)   $1  (size = ${size}Kb, deleted = $datetime)"
   fi
   index=$(( $index + 1))
 done
 
 echo ""
 echo -n "Which version of $1 do you want to restore ('0' to quit)?[1] : "
 read desired
 
  if[ ${desired:=1} -ge $index ] ; then
   echo "$0: Restore cancelled by user: index value too big.">&2
   exit 1
  fi
 
  if[ $desired -lt 1 ] ; then
   echo "$0: restore cancelled by user." >&2 ; exit 1
  fi
 
 restore="$(ls -td1 *"$1" | sed -n"${desired}p")"
 
  if[ -e "$dest/$1" ] ; then
    echo "\"$1\" already exists inthis directory. Cannot overwrite." >&2
   exit 1
  fi
 
 echo -n "Restoring file \"$1\" ..."
 $move "$restore" "$dest/$1"
 echo "done."
 
 echo -n "Delete the additional copies of this file? [y] "
 read answer
 
  if[ ${answer:=y} = "y" ] ; then
   $realrm -rf *"$1"
   echo "deleted."
 else
   echo "additional copies retained."
  fi
else
  if[ -e "$dest/$1" ] ; then
   echo "\"$1\" already exists in this directory. Cannotoverwrite." >&2
   exit 1
  fi
 
 restore="$(ls -d *"$1")"
 
 echo -n "Restoring file \"$1\" ... "
 $move "$restore" "$dest/$1"
 echo "done."
fi
 
exit 0

logrm.sh

#!/bin/sh
# logrm - log all file deletion requests unless "-s" flag isused
 
removelog="/tmp/removelog.log"
 
if [ $# -eq 0 ] ; then
 echo "Usage: $0 [-s] list of files or directories" >&2
 exit 1
fi
 
if [ "$1" = "-s" ] ;then
  #silent operation requested... don't log
 shift
else
 echo "$(date): ${USER}: $@" >> $removelog
fi
 
/bin/rm "$@"
 
exit 0

formaidir.sh

#!/bin/sh
 
# formatdir - output a directory listing ina friendly and useful format
 
gmk()
{
  #given input in Kb, output in Kb, Mb or Gb for best output format
  if[ $1 -ge 1000000 ] ; then
   echo "$(scriptbc -p 2 $1 / 1000000)Gb"
 elif [ $1 -ge 1000 ] ; then
   echo  "$(scriptbc -p 2 $1 /1000)Mb"
 else
   echo "${1}Kb"
  fi
}
 
if [ $# -gt 1 ] ; then
 echo "Usage: $0 [dirname]" >&2; exit 1
elif [ $# -eq 1 ] ; then
  cd"$@"
fi
 
for file in *
do
  if[ -d "$file" ] ; then
   size=$(ls "$file" | wc -l | sed 's/[^[:digit:]]//g')
   if [ $size -eq 1 ] ; then
     echo "$file ($size entry)|"
   else
     echo "$file ($size entries)|"
   fi
 else
   size="$(ls -sk "$file" | awk '{print $1}')"
   echo "$file ($(gmk $size))|"
  fi
done | \
  sed's/ /^^^/g'  | \
 xargs -n 2     | \
  sed's/\^\^\^/ /g' | \
  awk-F\| '{ printf "%-39s %-39s\n", $1, $2 }'
 
exit 0

locate.sh

#!/bin/sh
 
# locate - search the locate database forthe specified pattern
 
locatedb="/var/locate.db"
 
exec grep -i "$@" $locatedb

mklocatedb.sh

#!/bin/sh
 
# mklocatedb - build the locate databaseusing find. Must be root to run this
 
locatedb="/var/locate.db"
 
if [ "$(whoami)" !="root" ] ; then
 echo "Must be root to run this command." >&2
 exit 1
fi
 
find / -print > $locatedb
 
exit 0

DIR.sh

#!/bin/sh
# DIR - pretend we're the DIR command in DOS and display the contents
#   of the specified file, accepting some of the standard DIR flags
 
usage()
{
cat << EOF >&2
 Usage: $0 [DOS flags] directory or directories
 Where:
   /D              sort by columns
   /H                show help for this shell script
   /N              showlong listing format with filenames on right
  /OD           sort by oldest to newest
  /O-D           sort by newest tooldest
   /P             pauseafter each screenful of information
   /Q                show owner of the file
   /S                 recursive listing
   /W             usewide listing format
EOF
 exit 0
}
 
postcmd=""
flags=""
 
while [ $# -gt 0 ]
do
 case $1 in
   /D     ) flags="$flags-x"                ;;
   /H        ) usage                          ;;
    /[NQW]) flags="$flags -l"                  ;;
   /OD    ) flags="$flags-rt"              ;;
   /O-D   ) flags="$flags-t"                ;;
   /P     ) postcmd="more"               ;;
   /S     ) flags="$flags-s"                 ;;
          * ) # unknown flag: probably a dir specifier
                 break;       #so let's get outta the while loop
 esac
 shift            # processed flag, let's see if there'sanother
done
 
# done processing flags, now the commanditself:
 
if [ ! -z "$postcmd" ] ; then
  ls$flags "$@" | $postcmd
else
  ls$flags "$@"
fi
 
exit 0

findman.sh

#!/bin/sh
 
# findman -- given a pattern and a mansection, show all the matches
#  for that pattern from within all relevant man pages.
 
match1="/tmp/$0.1.$$"
matches="/tmp/$0.$$"
manpagelist=""
 
trap "rm -f $match1 $matches"EXIT
 
case $#
in
  3 )section="$1" cmdpat="$2" manpagepat="$3"           ;;
  2 )section=""   cmdpat="$1" manpagepat="$2"           ;;
  * )echo "Usage: $0 [section] cmdpattern manpagepattern" >&2
     exit 1
esac
 
if ! man -k "$cmdpat" | grep"($section" > $match1 ; then
 echo "No matches to pattern \"$cmdpat\". Try somethingbroader?"; exit 1
fi
 
cut -d\( -f1 < $match1 > $matches  # command names only
cat /dev/null > $match1                  #clear the file...
 
for manpage in $(cat $matches)
do
 manpagelist="$manpagelist $manpage"
  man$manpage | col -b | grep -i $manpagepat | \
   sed "s/^/${manpage}: /" | tee -a $match1
done
 
if [ ! -s $match1 ] ; then
cat << EOF
Command pattern "$cmdpat" hadmatches, but within those there were no
matches to your man page pattern"$manpagepat" found in that set.
Man pages checked:$manpagelist
EOF
fi
 
exit 0
 

timein.sh

#!/bin/sh
 
# timein - show the current time in thespecified timezone or
#  geographic zone. Without any argument, show UTC/GMT. Use
#  the word "list" to see a list of known geographic regions
#   Notethat it's possible to match a zone directory (a region)
#  but that only timezone files are valid specifications.
 
#  Timezone database ref: http://www.twinsun.com/tz/tz-link.htm
 
zonedir="/usr/share/zoneinfo"
 
if [ ! -d $zonedir ] ; then
 echo "No timezone database at $zonedir." >&2 ; exit 1
fi
 
if [ -d "$zonedir/posix" ] ; then
 zonedir=$zonedir/posix        #modern Linux systems
fi
 
if [ $# -eq 0 ] ; then
 timezone="UTC"
 mixedzone="UTC"
elif [ "$1" = "list" ]; then
  (echo "All known timezones and regions defined on this system:"
   cd $zonedir
   find * -type f -print | xargs -n 2 | \
     awk '{ printf "  %-38s%-38s\n", $1, $2 }'
  ) |more
 exit 0
else
 
 region="$(dirname $1)"
 zone="$(basename $1)"
 
  #Is it a direct match?  If so,  we're good to go. Otherwise we need
  #to dig around a bit to find things. Start by just counting matches
 
 matchcnt="$(find $zonedir -name $zone -type f -print |
       wc -l | sed 's/[^[:digit:]]//g' )"
 
  if[ "$matchcnt" -gt 0 ] ; then      # at least one file matches
   if [ $matchcnt -gt 1 ] ; then      # more than one file match
     echo "\"$zone\" matches more than one possible time zonerecord." >&2
     echo "Please use 'list' to see all known regions andtimezones" >&2
     exit 1
   fi
   match="$(find $zonedir -name $zone -type f -print)"
   mixedzone="$zone"
 else
    #Normalize to first upper, rest of word lowercase for region + zone
   mixedregion="$(echo ${region%${region#?}} | tr '[[:lower:]]''[[:upper:]]')\
$(echo ${region#?} | tr '[[:upper:]]''[[:lower:]]')"
   mixedzone="$(echo ${zone%${zone#?}} | tr '[[:lower:]]''[[:upper:]]')\
$(echo ${zone#?} | tr '[[:upper:]]''[[:lower:]]')"
   
   if [ "$mixedregion" != "." ] ; then
     # only look for specified zone in specified region
     # to let users specify unique matches when there's more than one
     # possibility (e.g., "Atlantic")
     match="$(find $zonedir/$mixedregion -type f -name $mixedzone-print)"
   else
     match="$(find $zonedir -name $mixedzone -type f -print)"
   fi
 
   if [ -z "$match"  ] ;then  # no file matches specified pattern
     if [ ! -z $(find $zonedir -name $mixedzone -type d -print) ] ; then
       echo \
   "The region \"$1\" has more than one timezone. Please use'list'" >&2
     else  #  just not a match at all
       echo "Can't find an exact match for \"$1\". Please use'list'" >&2
     fi
     echo "to see all known regions and timezones." >&2
     exit 1
   fi
  fi
 timezone="$match"
fi
 
nicetz=$(echo $timezone | sed"s|$zonedir/||g")     # prettyup the output
 
echo It\'s $(TZ=$timezone date '+%A, %B %e,%Y, at %l:%M %p') in $nicetz
 
exit 0

remember.sh

#!/bin/sh
 
#  remember- an easy command-line based memory pad
#   search the results with 'remindme'
 
rememberfile="$HOME/.remember"
 
if [ $# -eq 0 ] ; then
 echo "Enter note, end with ^D: "
  cat- >> $rememberfile
else
 echo "$@" >> $rememberfile
fi
 
exit 0

remindme.sh

#!/bin/sh
 
# remindme - search a datafile for matchinglines, or show the contents
#  of the datafile if no arg is specified
 
rememberfile="$HOME/.remember"
 
if [ $# -eq 0 ] ; then
 more $rememberfile
else
 grep -i "$@" $rememberfile | ${PAGER:-more}
fi
 
exit 0

calc.sh

#!/bin/sh
 
# calc - a command-line calculator thatacts as a front-end to bc
 
scale=2
 
show_help()
{
cat << EOF
  Inaddition to standard math functions, calc also supports
 
  a %b       remainder of a/b
  a ^b       exponential: a raised to the bpower
 s(x)        sine of x, x in radians
 c(x)        cosine of x, x inradians
 a(x)        arctangent of x,returns radians
 l(x)        natural log of x
 e(x)        exponential log ofraising e to the x
 j(n,x)      bessel function ofinteger order n of x
  scaleN     show N fractional digits (default =2)
EOF
}
 
if [ $# -gt 0 ] ; then
 exec scriptbc "$@"
fi
 
echo "Calc - a simple calculator. Use'help' for help, 'quit' to quit."
 
echo -n "calc> "
 
while read command args
do
 case $command
  in
   quit|exit) exit 0                                              ;;
   help|\?)   show_help                                ;;
   scale)     scale=$args                             ;;
   *)         scriptbc -p $scale"$command" "$args"    ;;
 esac
 
 echo -n "calc> "
done
 
echo ""
 
exit 0

checkspelling.sh

#!/bin/sh
 
# checkspelling - check the spelling of aword
 
spell="ispell -l"          # if you have ispell installed instead
                              # if not, just define spell=spell or
                              # equivalent.
 
if [ $# -lt 1 ] ; then
 echo "Usage: $0 word or words" >&2
 exit 1
fi
 
for word
do
  if[ -z $(echo $word | $spell) ] ; then
   echo "$word:            spelledcorrectly."
 else
   echo "$word:            misspelled."
  fi
done
 
exit 0

你可能感兴趣的:(SUSE相关)