These sections contain some examples of Bourne shell scripts.
A script named fez performs an anonymous ftp get or list. Refer to the Description comments in the script for information about how the FTP site is determined.
#!/bin/sh # # @(#)fez,v1.0 ([email protected]) 08/29/92 # PATHNAME=anywhere.EBay:/home/me/bin/fez MYNAME=`basename $0` # # Author: # Wayne Thompson # # Synopsis: usage=`/bin/sed -e "s/^ *//" << endusage usage: $MYNAME [-h] [-abfglmprR] [[login@]hostname:[sourcepath]] endusage` # # Description: # This script will perform an anonymous ftp get or list. # # If the hostname is not specified on the command line, then # it is derived from the basename(1) of the current directory. # This provides for a hierarchy of hostnames within which to # get files or directory listings. # # If no flags and arguments are given or a single argument of # the form "hostname:" is given, the default action will be # to retrieve a recursive directory listing from the remote # host into the file "./ls-lR.". # # Directory listings are named in the following manner: # <the command used to produce the listing w/spaces collapsed> # followed by the path it was produced from with slashes(/) # transliterated to dots(.). e.g. # ls-l. (ls -l /) # ls-lR.a.b (ls -lR /a/b) # # When mirroring is enabled (default), the directory listing # "ls-lR.a.b" would be placed in the directory "./a/b" which # would be created if necessary. # Likewise, "fez export.lcs.mit.edu:/contrib/3dlife.c" would # get "/contrib/3dlife.c" from "export.lcs.mit.edu" and place # it into "./contrib/3dlife.c". # An alternative behavior is provided by the "-f" flag, which # serves to flatten the destination hierarchy. # "fez -f export.lcs.mit.edu:/contrib/3dlife.c" would get # "/contrib/3dlife.c" into "./3dlife.c" # # The default user is "anonymous". # The default password is one of: # internal to Sun = $USER@hostname # external to Sun = [email protected] # You may override these in $HOME/.netrc (see netrc(5)) # or from the command line. # # Options: # -a ascii mode # -b binary mode (default) # -f flatten hierarchy # -g get (default w/arg) # -h print command description. # -l list (default w/o arg) # -m mirror hierarchy (default) # -p passwd password # -(r|R) recursive (default w/o arg) # # Environment: # # Files: # $HOME/.netrc file for ftp remote login data # # Diagnostics: # Exit Status: # 0 normal termination # 1 abnormal termination # # Errors (stderr): # usage # # Warnings (stderr): # # Info (stdout): # # Dependencies: # Fez only knows how to talk to UNIX(R) hosts. # # Caveats: # A recursive directory get will not fetch subdirectories unless # they already exist. # # Bugs: # # >> BEGIN parse options >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # while [ $# -gt 0 ] do case $1 in -??*) # bundled options opts=$1 while [ $opts ] do opts=`/bin/expr $opts : '.(.*)'` case $opts in a*) # ascii mode mode=asci ;; b*) # binary mode mode=binary ;; f*) # flatten remote hierarchy flat=true ;; g*) # get ;; l*) # list list=true ;; p) passflg=true shift if [ $# -eq 0 ] then echo >&2 "$MYNAME: error: no passwd" echo >&2 "usage" exit 1 fi passwd=$1 ;; p*) echo >&2 "$MYNAME: error: p: must be last element of bundled options" exit 1 ;; [rR]*) # recursive recurse=true ;; ?*) echo >&2 "$MYNAME: error: -`/bin/expr $opts : '(.)'`: unknown option." echo >&2 "$usage" exit 1 ;; esac done shift ;; -a) # ascii mode mode=ascii shift ;; -b) # binary mode mode=binary shift ;; -f) # flatten remote hierarchy flat=true shift ;; -g) # get shift ;; -h) # help /bin/awk ' /^$/ { exit; } /^[# :]/ && NR > 1 { print substr ($0, 3); } ' $0 | /bin/sed " /^$/{ N /^ $/D } s/$MYNAME/$MYNAME/ " exit 0 ;; -l) # list list=true shift ;; -m) # mirror remote hierarchy mirror=true shift ;; -p) passflg=true shift if [ $# -eq 0 ] then echo >&2 "$MYNAME: error: no passwd" echo >&2 "usage" exit 1 fi passwd=$1 shift ;; -[rR]) # recursive recurse=true shift ;; --) # end of options shift break ;; -*) echo >&2 "$MYNAME: error: $1: unknown option." echo >&2 "$usage" exit 1 ;; *) # end of options break ;; esac done # << END parse options <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # # >> BEGIN parse arguments >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # case $# in 0) list=true recurse=true ;; 1) case $1 in *:) list=true recurse=true ;; esac ;; *) echo >&2 "$MYNAME: error: unexpected argument(s)." echo >&2 "$usage" exit 1 ;; esac # << END parse arguments <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # # >> BEGIN initialization >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # [ umask -ge 700 ] && umask `/bin/expr `umask` - 0700` # return unrooted dirname dirname () { expr './'${1-.}'/' : '(.)/[^/]*/$' | ${1-.}'/' : '/*(.*[^/])//*[^/][^/]*//*$' | . } [ ${1-.} = / ] && set . host=`/bin/expr "$1" : '[^@]*@(.*):' | "$1" : '(.*):' | `/bin/basename \`pwd\`` ` path=`/bin/expr "$1" : '[^:]*:(.*)' | $1. : '[^:]*:(.*)' | ${1-.}` dir=`dirname $path` file=`/bin/basename $path` login=`/bin/expr "$1" : '([^@]*)@' | anonymous` if /bin/ypmatch $host hosts.byname 2>&- 1>&- || /bin/ypmatch $host hosts.byaddr 2>&- 1>&- then port=21 passwd=${passwd-USER@`hostname`} else port=4666 passwd=${[email protected]} machine=$host host=sun-barr.EBay fi if [ $list ] then cmd="ls -l${recurse+R}" file=ls-l${recurse+R}`expr $path : '(.)$' | $dir$file : '(..*)' | /$dir/$file | tr / . ` dir=$path else cmd=${recurse+m}get [ $recurse ] && dir=$path && file=* fi case $1 in *@*:*) ;; *) [ $passflg ] || eval ` /bin/awk ' /machine *'"${machine-$host}"'/ { for (i = 1; i <= NF; i++) { if ($i == "login") print "login="$++i";"; if ($i == "password") print "passwd="$++i";"; } exit; } ' $HOME/.netrc 2>&- ` ;; esac # << END initialization <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # # >> BEGIN verify prerequisites >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # if [ ! "$flat" ] then /bin/mkdir -p $dir 2>&- cd $dir fi # << END verify prerequisites <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< # # >> BEGIN main >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # /usr/ucb/ftp -i -n -v $host $port << EOFTP user $login${machine+@$machine} $passwd ${mode-binary} cd $dir $cmd $file quit EOFTP echo "" # << END main <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #
The arch.sh.fctn script emulates SunOS 4.x system architecture.
# # %M%: Version: %I% Date: %G% # [ $_Arch_loaded ] || { # Function: # @(#)Arch ([email protected]) 05/14/92 # # Description: # This function emulates 4.x arch(1). # # Variables: # # Usage: # Arch # Arch -k # Arch archname # # Return: # 0 success # 1 non-success # # Dependencies: # This function works under SunOs 3.x - 5.x. # # Bugs: # Arch () { case $1 in '') /bin/arch $* 2>&- || /bin/expr `/bin/uname -m` : '(sun[0-9]*)' ;; -k) /bin/arch $* 2>&- || /bin/uname -m ;; *) if [ -x /bin/arch ] then /bin/arch $* else [ $* = `/bin/expr `/bin/uname -m` : '(sun[0-9]*)'` ] fi ;; esac } _Arch_loaded=1 }
The following function extends the functionality of the Bourne shell to include associative arrays.
## >> BEGIN package: arrays >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ## # Package: # @(#)arrays,v1.0 ([email protected]) 05/02/93 # # Description: # This package contains functions that emulate associative arrays. # Keys are limited to letters, digits, underscores, hyphens and periods. # # Variables: # __array_size_<array> # __array_keys_<array> # __array__<array>_<key> # __array_filename # __array_name # __array_key # __array_keys # __array_cell # # Usage: # setarray array key [value ...] # getarray array key # unsetarray array [key ...] # keys array # sizearray array # defined array [key] # dumparray pathname [array ...] # # Dependencies: # Array names and keys are combined to form strings which are # evaluated as parameters. # # Bugs: # ### >> BEGIN function: setarray >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ### # Function: # @(#)setarray,v1.0 ([email protected]) 05/16/93 # # Description: # This function assigns values to array elements. If more than one # value is provided and the key is an integer, values will be # assigned to successive elements beginning with the initial key. # # Variables: # __array_size_<array> # __array_keys_<array> # __array__<array>_<key> # __array_name # __array_key # __array_cell # # Usage: # setarray array key [value ...] # setarray pathname # # Return: # # Dependencies: # # Bugs: # setarray () { case $# in 0) echo >&2 setarray: error: "$@" echo >&2 usage: setarray array key '[value ...]' exit 1 ;; 1) if [ -f $1 ] then while read __array_name __array_key __array_value do setarray $__array_name $__array_key $__array_value done < $1 return else echo >&2 setarray: error: $1: no such file exit 1 fi ;; 2|3) ;; *) case $2 in [0-9]*) ;; *) echo >&2 setarray: error: "$@" echo >&2 setarray: error: 2nd argument must be an integer exit 1 ;; esac ;; esac __array_name=$1 __array_key=$2 case $2 in *[-.]*) __array_cell=`echo $2 | /bin/tr '[-.]' __` shift 2 set $__array_name $__array_cell "$@" ;; esac eval " if [ ${__array_size_$1+1} ] then [ ${__array__$1_$2+1} ] || { __array_size_$1=`/bin/expr $__array_size_$1 + 1` __array_keys_$1="$__array_keys_$1 $__array_key " } else __array_size_$1=1 __array_keys_$1=$__array_key fi __array__$1_$2=$3 " case $# in 2) shift 2 ;; *) shift 3 ;; esac while [ $# -gt 0 ] do __array_key=`/bin/expr $__array_key + 1` eval " [ ${__array__${__array_name}_$__array_key+1} ] || { __array_size_$__array_name=`/bin/expr $__array_size_$__array_name + 1` __array_keys_$__array_name="$__array_keys_$__array_name $__array_key" } __array__${__array_name}_$__array_key=$1 " shift done } ### << END function: setarray <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ### ### >> BEGIN function: getarray >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ### # Function: # @(#)getarray,v1.0 ([email protected]) 05/02/93 # # Description: # This function prints array values. # # Variables: # __array__<array>_<key> # __array_name # # Usage: # getarray array [key ...] # # Return: # # Dependencies: # # Bugs: # getarray () { case $# in 0) echo >&2 getarray: error: "$@" echo >&2 usage: getarray array '[key ...]' exit 1 ;; 1) # entire array set $1 `keys $1` ;; esac __array_name=$1 shift while [ $# -gt 0 ] do case $1 in *[-.]*) eval echo $__array__${__array_name}_`echo $1 | /bin/tr '[-.]' __` ;; *) eval echo $__array__${__array_name}_$1 ;; esac shift done } ### << END function: getarray <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ### ### >> BEGIN function: unsetarray >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ### # Function: # @(#)unsetarray,v1.0 ([email protected]) 05/02/93 # # Description: # This function unsets (undefines) one or more array elements # or an entire array. # # Variables: # __array_size_<array> # __array_keys_<array> # __array__<array>_<key> # __array_name # __array_key # __array_keys # # Usage: # unsetarray array [key ...] # # Return: # # Dependencies: # # Bugs: # unsetarray () { case $# in 0) echo >&2 unsetarray: error: "$@" echo >&2 usage: unsetarray array '[key ...]' exit 1 ;; 1) # entire array set $1 `keys $1` ;; esac __array_name=$1 shift while [ $# -gt 0 ] do eval " __array_keys= [ ${__array__${__array_name}_$1+1} ] && for __array_key in $__array_keys_$__array_name do case $__array_key in $1) case $1 in *[-.]*) unset __array__${__array_name}_`echo $1 | /bin/tr '[-.]' __` ;; *) unset __array__${__array_name}_$1 ;; esac __array_size_$__array_name=`/bin/expr $__array_size_$__array_name - 1` ;; *) case $__array_keys in '') __array_keys=$__array_key ;; *) __array_keys="$__array_keys $__array_key" ;; esac ;; esac done __array_keys_$__array_name=$__array_keys " shift done eval " case $__array_size_$__array_name in 0) unset __array_size_$__array_name __array_keys_$__array_name ;; esac " } ### << END function: unsetarray <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ### ### >> BEGIN function: keys >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ### # Function: # @(#)keys,v1.0 ([email protected]) 05/02/93 # # Description: # This function prints the keys of an array. # # Variables: # __array_keys_<array> # # Usage: # keys array # # Return: # # Dependencies: # # Bugs: # keys () { case $# in 1) eval echo $__array_keys_$1 ;; *) echo >&2 keys: error: "$@" echo >&2 usage: keys array exit 1 ;; esac } ### << END function: keys <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ### ### >> BEGIN function: sizearray >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ### # Function: # @(#)sizearray,v1.0 ([email protected]) 05/02/93 # # Description: # This function prints the number of defined array elements. # # Variables: # __array_size_<array> # # Usage: # sizearray array # # Return: # # Dependencies: # # Bugs: # sizearray () { case $# in 1) eval echo ${__array_size_$1:-0} ;; *) echo >&2 sizearray: error: "$@" echo >&2 usage: sizearray array exit 1 ;; esac } ### << END function: sizearray <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ### ### >> BEGIN function: defined >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ### # Function: # @(#)defined,v1.0 ([email protected]) 05/02/93 # # Description: # This function returns whether an array element or array is defined. # # Variables: # __array_size_<array> # __array__<array>_<key> # # Usage: # defined array [key] # # Return: # 0 defined # 1 undefined # # Dependencies: # # Bugs: # defined () { case $# in 1) eval set ${__array_size_$1+0} 1 ;; 2) case $2 in *[-.]*) set $1 `echo $2 | /bin/tr '[-.]' __`;; esac eval set ${__array__$1_$2+0} 1 ;; *) echo >&2 defined: error: "$@" echo >&2 usage: defined array '[key]' exit 1 ;; esac return $1 } ### << END function: defined <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ### ### >> BEGIN function: dumparray >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ### # Function: # @(#)dumparray,v1.0 ([email protected]) 05/02/93 # # Description: # This function dumps arrays in file in a format readable by # shell dot (.) command. # # Variables: # __array_filename # # Usage: # dumparray pathname [array ...] # # Return: # 0 success # 1 failure # # Dependencies: # # Bugs: # Since this depends on the output of set, and set does not preserve # quoting, the resultant file may be unusable. Use of # storearray/setarray is safer, albeit slower. # dumparray () { case $# in 0) echo >&2 dumparray: error: "$@" echo >&2 usage: dumparray pathname '[array ...]' exit 1 ;; esac __array_filename=$1 shift set | /bin/awk ' /(){$/ { exit } # functions follow parameters /^__array_(filename|name|key|keys|cell)=/ { next } # temp storage /^__array_(size|keys)*_('`echo ${*:-.*} | /bin/tr " " |`')(_|=)/ { if (NF > 1) { n = index($0, "="); print substr($0 , 1, n)"'''"substr($0, n+1)"'''"; } else { print; } } ' > $__array_filename } ### << END function: dumparray <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ### ## << END package: arrays <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##
The function scripts arch.sh.fctn (displayed earlier in this chapter), hostname.sh.fctn, osr.sh.fctn, and whoami.sh.fctn are used to help in the transition from SunOS 4.x to Solaris 2.x.
The hostname.sh.fctn script emulates the SunOS 4.x hostname command.
# # %M%: Version: %I% Date: %G% # [ $_Hostname_loaded ] || { # Function: # @(#)hostname ([email protected]) 02/15/92 # # Description: # This function emulates 4.x hostname(1) given no arguments. # # Variables: # # Usage: # Hostname # # Return: # # Dependencies: # This funcion works under SunOs 3.x - 5.x. # # Bugs: # Hostname () { /bin/hostname 2>&- || /bin/uname -n } _Hostname_loaded=1 }
The osr.sh.fctn script outputs the numeric portion of the current operating system release—for example, 5.2 for Solaris 5.2 system software.
# # %M%: Version: %I% Date: %G% # [ $_Osr_loaded ] || { # Function: # @(#)Osr ([email protected]) 02/08/92 # # Description: # This function outputs the numeric portion of the current OS release. # # Variables: # # Usage: # os=`Osr` # # Return: # 0 success # 1 non-success # # Dependencies: # This funcion works under SunOs 3.x - 5.x. # # Bugs: # Osr () { /bin/expr ` { /bin/uname -r || /bin/cat /usr/sys/conf*/RELEASE } 2>&- || /etc/dmesg | /bin/awk ' BEGIN { status = 1 } /^SunOS Release/ { print $3; status = 0; exit } END { exit status } ' || /bin/expr "` /usr/ucb/strings -50 /vmunix | /bin/egrep '^SunOS Release' `" : 'SunOS Release ([^ ]*)' ` : '([.0-9]*)' } _Osr_loaded=1 }
The whoami.sh.fctn emulates the SunOS 4.x whoami command.
# # @(#) whoami.sh.fctn 1.2 Last mod: 6/4/93 # [ $_Whoami_loaded ] || { # Function: # @(#)whoami ([email protected]) 03/20/92 # # Description: # This function emulates 4.x whoami(1). # # Variables: # # Usage: # whoami # # Return: # # Dependencies: # This funcion works under SunOs 3.x - 5.x. # # Bugs: # Whoami () { /usr/ucb/whoami 2>&- || /bin/expr "`/bin/id`" : '[^(]*(([^)]*)' } _Whoami_loaded=1 }
3.142.133.180