比較的簡単だと思いますが、どうすればいいのか分かりません。
#!/usr/bin/ksh
set `iostat`
myvar=6
echo ${$myvar}
のように解釈したい${$myvar}
-> ${6}
-> value
これは、kshを含む多くのファインシェルに組み込まれているeval
を使用して実行できます。
#!/usr/bin/ksh
set $(iostat)
myvar=6
eval "echo \${$myvar}"
トリックは、eval
にフィードする文字列を二重引用符で囲んで、$ myvarが「6」に置き換えられるようにし、外側のドル記号をバックスラッシュしてeval
が文字列を取得するようにすることです。 $ 6 "。
出力用に「%user」を取得しましたが、マルチプロセッサRHELマシンで試しました。
最近の高度なシェルには、別の変数に名前が格納されている変数の値を参照するメソッドがあります。残念ながら、この方法はksh、bash、zshで異なります。
Mksh≥R39bでは、myvar
を名前参照にすることができます。
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}
Ksh88やpdkshを含む古いシェルでは、別の変数名を含む変数があり、この変数の値を使用したい場合にのみ頼むことができますeval
、 Bruce Edigerで説明 。このソリューションは、すべてのBourne/POSIXシェルで機能します。
eval "value=\${$myvar}"
echo "$value"
これはここでの最良の方法です。よりシンプルで移植性があります。
ユースケースでは、配列を持つシェル(すべてのkshバリアント、bash≥2.0、zsh)で、配列変数に割り当てて、必要な要素を取ることができます。 kshおよびbash配列の番号は0から始まりますが、setopt ksh_arrays
またはemulate ksh
を発行しない限り、zshは1から始まります。
set -A iostat -- $(iostat)
echo "${iostat[5]}"
位置パラメータを配列変数a
にコピーする場合:
set -A a -- "$@"
Ksh93、mksh≥R39b、bash≥2.0、zshでは、配列割り当て構文を使用できます。
iostat=($(iostat))
echo "${iostat[5]}"
Gilles(回答のbash
の部分を提供した)が示したように、Bruce Edigerの(eval
を使用して移植する方法について)も無効にしないでください。ここにnameref
in最近のmksh
(およびAT&T ksh93、ただし@Gillesがコメントしたように、namerefsはAT&T kshの定位置パラメーターを参照できず、名前付きパラメーターのみを参照):
#!/bin/mksh
set -- $(iostat)
nameref myvar=6
echo $myvar
抵抗を改善するため、set
の後に--
を追加しました。
しばらくkshやその他のバリアントを使用していないため、ksh(またはbash)に同様の機能があるかどうかはわかりません。私の主なシェルは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
小さなチャンクの方がはるかに扱いやすいと思います。コードによっては、間接変数参照を使用する必要がある場合とない場合があります。それがどのように機能するかを知ることは、それでも知ることは良いことです。自分で使っています。