简体   繁体   中英

Elegant use of arrays in ksh

I'm trying build an sort of property set in ksh.

Thought the easiest way to do so was using arrays but the syntax is killing me.

What I want is to

  1. Build an arbitrary sized array in a config file with a name and a property.
  2. Iterate for each item in that list and get that property.

I theory what I wish I could do is something like

MONITORINGSYS={
    SYS1={NAME="GENERATOR" MONITORFUNC="getGeneratorStatus"}
    SYS2={NAME="COOLER" MONITORFUNC="getCoolerStatus"}
}

Then later on, be able to do something like:

for CURSYS in $MONITORINGSYS
do
    CSYSNAME=$CURSYS.NAME
    CSYSFUNC=$CURSYS.MONITORFUNC

    REPORT="$REPORT\n$CSYSNAME"

    CSYSSTATUS=CSYSFUNC $(date)
    REPORT="$REPORT\t$CSYSSTATUS"
done
echo $REPORT

Well, that's not real programming, but I guess you got the point..

How do I do that?

[EDIT]

I do not mean I want to use associative arrays. I only put this way to make my question more clear... Ie It would not be a problem if the loop was something like:

for CURSYS in $MONITORINGSYS
do
    CSYSNAME=${CURSYS[0]}
    CSYSFUNC=${CURSYS[1]}

    REPORT="$REPORT\n$CSYSNAME"

    CSYSSTATUS=CSYSFUNC $(date)
    REPORT="$REPORT\t$CSYSSTATUS"
done
echo $REPORT

Same applies to the config file.. I'm just looking for a syntax that makes it minimally readable.

cheers

Not exactly sure what you want... Kornshell can handle both associative and indexed arrays.

However, Kornshell arrays are one dimensional. It might be possible to use indirection to emulate a two dimensional array via the use of $() and eval. I did this a couple of times in the older Perl 4.x and Perl 3.x, but it's a pain. If you want multidimensional arrays, use Python or Perl.

The only thing is that you must declare arrays via the typedef command:

$ typeset -A foohash    #foohash is an associative array
$ typeset -a foolist    #foolist is an integer indexed array.

Maybe your script can look something like this

typeset -a sysname
typeset -a sysfunct

sysname[1] = "GENERATOR"
sysname[2] = "COOLER"
sysfunc[1] = "getGeneratorStatus"
sysfunc[2] = "getCoolerStatus"

for CURSYS in {1..2}
do
   CSYSNAME="${sysname[$CURSYS]}"
   CSYSFUNC="${sysfunc[$CURSYS]}"
   REPORT="$REPORT\n$CSYSNAME"
   CSYSSTATUS=$(eval "CSYSFUNC $(date)")
   REPORT="$REPORT\t$CSYSSTATUS"
done
echo $REPORT

ksh93 now has compound variables which can contain a mixture of indexed and associative arrays. No need to declare it as ksh will work it out itself.

#!/bin/ksh

MONITORINGSYS=(
        [SYS1]=(NAME="GENERATOR" MONITORFUNC="getGeneratorStatus")
        [SYS2]=(NAME="COOLER" MONITORFUNC="getCoolerStatus")
)

echo MONITORING REPORT
echo "-----------------"

for sys in ${!MONITORINGSYS[*]}; do
        echo "System:    $sys"
        echo "Name:      ${MONITORINGSYS[$sys].NAME}"
        echo "Generator: ${MONITORINGSYS[$sys].MONITORFUNC}"
        echo
done

Output:

MONITORING REPORT
-----------------
System:    SYS1
Name:      GENERATOR
Generator: getGeneratorStatus

System:    SYS2
Name:      COOLER
Generator: getCoolerStatus

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM