ksh 中数组的优雅使用

发布于 2024-11-26 15:30:07 字数 1002 浏览 2 评论 0原文

我正在尝试在 ksh 中构建一种属性集。

我认为最简单的方法是使用数组,但语法让我很苦恼。

我想要的是

  1. 在配置文件中构建一个具有名称和属性的任意大小的数组。
  2. 迭代该列表中的每个项目并获取该属性。

我理论上希望我能做的是类似的事情

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

然后稍后,能够做类似的事情:

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

嗯,这不是真正的编程,但我想你明白了......

我该怎么做?

[编辑]

我并不是说我想使用关联数组。我这样做只是为了让我的问题更清楚...即,如果循环类似于:

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

同样适用于配置文件..我只是在寻找一种使其可读性最低的语法。

干杯

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

稳稳的幸福 2024-12-03 15:30:07

不太确定你想要什么... Kornshell 可以处理关联数组和索引数组。

然而,Kornshell 数组是一维的。通过使用 $() 和 eval 可以使用间接来模拟二维数组。我在较旧的 Perl 4.x 和 Perl 3.x 中这样做过几次,但这很痛苦。如果需要多维数组,请使用 Python 或 Perl。

唯一的问题是您必须通过 typedef 命令声明数组:

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

也许您的脚本看起来像这样

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

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
夜清冷一曲。 2024-12-03 15:30:07

ksh93 现在具有复合变量,可以包含索引数组和关联数组的混合。无需声明,因为 ksh 会自行解决。

#!/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

输出:

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

System:    SYS2
Name:      COOLER
Generator: getCoolerStatus

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文