#!/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 (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 } # -------------------- 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 truned of with your own 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 # 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` # 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=$def)? " ;; *) echo >&4 "$1 (def=$def)? " echo >&2 "Unknown default \"$def\" - aborting" exit 1 ;; esac input='' read input [ -z "$input" ] && input=$def 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 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>&- }