#!/bin/echo "Source only Script" # # Define a huge set of general shell functions to perform various tasks. # This file can be shell sourced to define all the functions given # # For stand alone shell scripts it is recomended that the individual routines # be copy and pasted into the shell script itself. # # NOTE: some of the following routines use the following file descriptors # 0, 1, 2 Default STDIN, STDOUT, STDERR # 3, 4, 5 Save of STDIN, STDOUT, STDERR # echo without return (that works on all systems) if [ "X`echo -n`" = "X-n" ]; then echo_n() { echo ${1+"$@"}"\c"; } else echo_n() { echo -n ${1+"$@"}; } fi # Is command available # Eg: if cmd_found COMMAND; then COMMAND args; fi cmd_found() { expr match "`type $1 2>&1`" '.*not found' == 0 >/dev/null } # Replacement 'seq' with format and start incr end options # Just like the real thing (missing floating-point and reverse options) # Requires "printf" (or some equivelent) to be available. # # Examples # seq_format -f "%03d" 15 # seq_format 1 10 # seq_format 1 2 15 # if cmd_found seq; then :; else seq() { if [ "X$1" = "X-f" ] then format="$2"; shift; shift else format="%d" fi case $# in 1) i=1 incr=1 end=$1 ;; 2) i=$1 incr=1 end=$2 ;; *) i=$1 incr=$2 end=$3 ;; esac while [ $i -le $end ]; do printf "$format\n" $i; i=`expr $i + $incr`; done } fi # Simplier restricted forms of "seq" # seq_count 10 seq_count() { i=1; while [ $i -le $1 ]; do echo $i; i=`expr $i + 1`; done } # simple_seq 1 2 10 simple_seq() { i=$1; while [ $i -le $3 ]; do echo $i; i=`expr $i + $2`; done } # -------------------- User Input ------------------- # Set to read single key strokes # EG; cbreak_on; key=`getkey`; cbreak_off # If using this style of input you should turn cbreak on continuously # BUT ensure it is turned off on exit using a trap command # exec 0<&3 # Save STDIN, -- must be terminal input cbreak_on() { stty 0<&3 cbreak -echo; } cbreak_off() { stty 0<&3 -cbreak echo; } getkey() { dd bs=1 count=1 0<&3 2>/dev/null } # Design your own trap # trap "cbreak_off; exit 0" 0 # trap "cbreak_off; exit 1" 1 2 3 15 # Turn of echo for password reads # EG; echo_off; read passwd; echo_on; echo '' echo_off() { stty -echo; } echo_on() { stty echo; } # User user a y/n/number question, with default answer (y,n,number) # For example: # install=`ask_user "Install this package" y` # install=`ask_user "Danger! Do you want to proceed?" n` # index=`ask_user "What file [1-10]" 0` # Output will be either "true", a empty string, or a number as appropriate # exec 4>&1 # save the default stdout for the next routine ask_user() { # Usage: ask question y/n case "$2" in y) echo_n >&4 "$1 (Y/n)? " ;; n) echo_n >&4 "$1 (y/N)? " ;; [0-9]*) echo_n >&4 "$1 (def=$2)? " ;; *) echo >&4 "$1 (def=$2)? " exit 1 ;; esac input='' read input [ -z "$input" ] && input="$2" case "$2" in n) [ "$input" = y -o "$input" = Y ] && echo "true" ;; y) [ "$input" = n -o "$input" = N ] || echo "true" ;; [0-9]*) expr "$input" + 0 2>/dev/null || echo '0' ;; # convert to a number *) echo "$input" ;; esac } # ---------------------- Network --------------------- # Convert Hostname <-> IP using the local machines named cache or /etc/hosts # Usally a lot faster than directly using the slow nslookup. # NOTE: The FQDN of an IP is the IP! fqdn() { perl -e 'print( (gethostbyname(shift))[0] || "", "\n");' $1 } ip_name() { perl -MSocket \ -e 'print( (gethostbyaddr( inet_aton(shift), AF_INET))[0] || "", "\n");' $1 } name_ip() { # return machines IP address or empty string perl -MSocket -e ' $ip = (gethostbyname(shift))[4] || ""; print $ip ? inet_ntoa( $ip ) : "", "\n"; ' $1 } ifconfig_ip() { # WARNING: for GU subnet use only ifconfig -a | sed -n 's/.*inet [^1]*\(132\.234\.[0-9.]*\).*/\1/p' } # Do a nslookup for FQDN with timeout - even if primary namserver is down # EG: fqdn=`nslookup_fqdn "$4.$3.$2.$1.in-addr.arpa"` TIMEOUT=5 nslookup_fqdn() { exec 5>&2 # save the default stderr for real offical errors { # Background the required command - note the process id nslookup <<-"EOF" | sed -n '/arpa/s/.*name \= //p' & set type=PTR $1 EOF cmd_pid=$! # # Wait for it (sleep pipeline) - note sleep's process id sleep $TIMEOUT | ( read nothing # wait on sleep to finish kill -0 $cmd_pid || exit # nslookup finished? - exit kill $cmd_pid # no -- kill it! echo >&5 "WARNING: nslookup failed to return in $TIMEOUT seconds!" ) & sleep_pid=$! # # wait for nslookup to finish or be killed wait $cmd_pid kill -0 $sleep_pid || return; # sleep finished? kill $sleep_pid # no - kill it } 2>/dev/null # get rid of all normal error output exec 5>&- } # ----------------------------------------------------------------------