Elegant use of arrays in ksh

妖精的绣舞 提交于 2021-01-28 12:11:08

问题


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... I.e. 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


回答1:


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



回答2:


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


来源:https://stackoverflow.com/questions/6847143/elegant-use-of-arrays-in-ksh

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!