On Thursday 06 September 2007 16:53, James Melin wrote:
>I am trying to get away from hard coded server names in a script using case
> for valid name check
>
>This works but is not good because as soon as you add a new server to the
> NFS mountpoint list the script this is from has to be changed.
>
>case $target_system in
>  abinodji | calhoun | itasca | nokomis | pepin | phalen | vadnais | bemidji
> | millpond | mudlake | terrapin | hadley | hyland ) parm_1="valid";; esac
>
>
>So I tried several variants of this:
>
>space=" "
>delim=" | "
>raw_list=`ls /clamscan/servers`     #read list of mountpoints
>cooked_list=$(echo $raw_list | sed -e "s:$space:$delim:g") #replace space
> with case-happy delimiters echo "Raw list = "$raw_list
>echo "cooked list = "$cooked_list
>case $target_system in
>  $cooked_list ) parm_1="valid" ;;
>esac
>
>But even though the display of 'cooked_list' seems to be what I want it to
> be, this never returns a match.
>
>Anyone see where I missed the turnip truck on this?

Yup: your $cooked_list inside that case statement represents a single pattern
whose value is a set of words separated by vertical bar characters and
whitespace.  What you want it to be is a list of separate patterns.  You see,
the shell breaks that case statement apart into words before doing parameter
substitutions, so it expects to parse the vertical bars separating multiple
patterns in a case before it expands that variable.

You could use eval to handle this, but there is a better way.  Don't use case
at all.  Define a simple InList() function that tells you if a given value is
in a list of values.  I use this in scripts all the time:

# Function to determine if a value is in a list of values.  The arguments
# are the value to check, and one or more other values which are the list
# to look for that first value in.  Returns zero if the first argument is
# repeated as any subsequent argument, or one if it is not.
InList()
{
local value="$1"
shift
while [ $# -ne 0 ]
do      if [ "$1" = "$value" ]; then return 0; fi
        shift
done
return 1
}

Note that this function uses only shell built-in commands, so it is pretty
efficient.  To get your list of known servers, do this:

Servers="$('ls' /clamscan/servers)"

Note that I'm using $(...) instead of backticks.  Backticks are evil!  I'm
also quoting the ls command to avoid any alias expansions, or you could
explicitly invoke /bin/ls.  Now you can do your check like this:

if InList "$target_system" $Servers
then    parm_1="valid"
fi

I encourage you to use functions extensively in your shell scripts.  They make
the code much easier to read!  You can use function arguments, the standard
input, and global variables as inputs to functions, and the return code,
standard output and global variables as outputs.  I don't recommend using
global variables other than as static inputs (eg. configuration values).
Here's a way to write InList() using standard input and output instead, which
shows the common idioms for doing that:

# Function to determine if a value is in a list of values.  The only argument
# is the value to check.  The standard input contains a list of other values
# to look for that first value in, one value per line.  Writes "valid" to the
# standard output if the argument is in the list on the standard input,
# otherwise there is no output.  There is no return value.
InList()
{
local item
while read item
do      if [ "$item" = "$1" ]; then echo "valid"; return; fi
done
}

It would be used like this:

parm_1="$('ls' -1 /clamscan/servers | InList "$target_system")"

Note: that's a "digit one" option to ls, not an "ell", to force the output to
have one server name per line.  This example does the same as the first
version, but is less efficient because it uses I/O mechanisms.  If you know
your server list is not going to be very long (< 10K bytes), then use the
first method.  If you want to handle lists of arbitrary size, use the I/O
method.
        - MacK.
-----
Edmund R. MacKenty
Software Architect
Rocket Software, Inc.
Newton, MA USA

----------------------------------------------------------------------
For LINUX-390 subscribe / signoff / archive access instructions,
send email to [EMAIL PROTECTED] with the message: INFO LINUX-390 or visit
http://www.marist.edu/htbin/wlvindex?LINUX-390

Reply via email to