我确信这相对简单,我只是不知道该怎么做。
#!/usr/bin/ksh
set `iostat`
myvar=6
我想要类似的东西echo ${$myvar}
,我想将其解释为${$myvar}
-> ${6}
->value
答案1
您可以使用eval
内置于许多优秀 shell 中的 来完成此操作,包括 ksh:
#!/usr/bin/ksh
set $(iostat)
myvar=6
eval "echo \${$myvar}"
技巧是用双引号引用您输入的字符串eval
,以便 $myvar 被“6”替换,并反斜杠外部的美元符号,以便eval
得到字符串“$6”。
我得到了“%user”的输出,但我在多处理器 RHEL 机器上尝试了它。
答案2
间接变量引用
现代高级 shell 有一种方法来引用名称存储在另一个变量中的变量的值。不幸的是,ksh、bash 和 zsh 之间的方法有所不同。
在 mksh ≥R39b 中,您可以创建myvar
一个 nameref:
typeset -n myvar=6
echo "$myvar"
这在 ATT ksh93 中不起作用,因为它不支持位置参数的名称引用。如果您有一个包含变量名称的变量,则可以使用此方法。
foo=bar
typeset -n myvar=foo
echo "$myvar" # prints bar
在bash≥2.0中,可以这样写
echo "${!myvar}"
在zsh中,你可以这样写
echo ${(P)myvar}
在较旧的 shell 中,包括 ksh88 和 pdksh,当您有一个包含另一个变量名的变量并且想要使用该变量的值时eval
,您唯一的办法是,正如布鲁斯·艾迪格所解释的。该解决方案适用于任何 Bourne/POSIX shell。
eval "value=\${$myvar}"
echo "$value"
使用数组
这是这里最好的方法:它更简单、更便携。
对于您的用例,在任何具有数组的 shell(所有 ksh 变体、bash ≥2.0、zsh)中,您可以分配给数组变量并获取您想要的元素。请注意,ksh 和 bash 数组从 0 开始编号,但 zsh 从 1 开始,除非您发出setopt ksh_arrays
或emulate ksh
。
set -A iostat -- $(iostat)
echo "${iostat[5]}"
如果要将位置参数复制到数组变量a
:
set -A a -- "$@"
在 ksh93、mksh ≥R39b、bash ≥2.0 和 zsh 中,可以使用数组赋值语法:
iostat=($(iostat))
echo "${iostat[5]}"
答案3
正如 Gilles(提供了bash
部分答案)所指出的,也没有使 Bruce Ediger 的(关于如何使用 进行便携式操作)无效,这是最近eval
如何使用(以及 AT&T ksh93,除了 – 正如@Gilles 评论的 – namerefs)不能引用 AT&T ksh 中的位置参数,只能引用命名参数):nameref
mksh
#!/bin/mksh
set -- $(iostat)
nameref myvar=6
echo $myvar
还添加了--
后set
以提高抵抗力。
答案4
数组的另一种用途
一段时间没有使用 ksh 或任何变体,所以我不确定 ksh(或 bash)是否具有类似的功能。我的主要 shell 是 zsh。我在处理类似命令的输出时使用数组iostat因为它们产生多行,并且并非所有行都具有相同的格式/长度。
#! /bin/zsh
IOStatOutput=("${(@f)$(iostat)}") # Produces one element per line
上面还绕过了位置参数的使用。现在,如果您想生成一系列设备:
for Element in {7..${#IOStatOutput}} # Devices listed in elements 7 thru the last
do
DevList+=( ${${=IOStatOutput[Element]}[1]} )
done
我发现较小的块更容易处理。您可能需要也可能不需要使用间接变量引用,具体取决于您的代码。知道它是如何工作的仍然是一件好事。我自己用的。