Я уверен, что это относительно просто, я просто не знаю, как это сделать.
#!/usr/bin/ksh
set `iostat`
myvar=6
Я хочу что-то подобное, echo ${$myvar}
которое я хочу интерпретировать как ${$myvar}
-> ${6}
->value
Я уверен, что это относительно просто, я просто не знаю, как это сделать.
#!/usr/bin/ksh
set `iostat`
myvar=6
Я хочу что-то подобное, echo ${$myvar}
которое я хочу интерпретировать как ${$myvar}
-> ${6}
->value
Ответы:
Вы можете сделать это с помощью eval
встроенных во многие тонкие оболочки, включая ksh:
#!/usr/bin/ksh
set $(iostat)
myvar=6
eval "echo \${$myvar}"
Хитрость заключается в том, eval
чтобы заключить в двойную кавычку строку, которую вы передаете, чтобы $ myvar заменялось на «6», и обратную косую черту внешнего знака доллара, чтобы eval
получить строку «$ 6».
Я получил «% user» для вывода, но я попробовал его на многопроцессорной машине RHEL.
vv=$( eval "echo \$$vn" )
. Благодаря тонну!
В современных расширенных оболочках есть метод для ссылки на значение переменной, имя которой хранится в другой переменной. К сожалению, метод отличается между ksh, bash и zsh.
В mksh ≥R39b вы можете сделать myvar
nameref:
typeset -n myvar=6
echo "$myvar"
Это не работает в ATT ksh93, потому что он не поддерживает nameref для позиционных параметров. Если у вас есть переменная, содержащая имя переменной, вы можете использовать этот метод.
foo=bar
typeset -n myvar=foo
echo "$myvar" # prints bar
В bash ≥2.0 вы можете написать
echo "${!myvar}"
В зш можно написать
echo ${(P)myvar}
В более старых оболочках, включая ksh88 и pdksh, вы можете использовать только те переменные, которые содержат имя другой переменной и хотите использовать значение этой переменной eval
, как объяснил Брюс Эдигер . Это решение работает в любой оболочке Bourne / POSIX.
eval "value=\${$myvar}"
echo "$value"
Это лучший метод здесь: он проще и более переносим.
Для вашего случая использования в любой оболочке с массивами (все варианты 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]}"
eval "vv=\${$vn}"
. Merci Beaucoup, добрый сэр.
Как указал Жиль (предоставивший bash
часть ответа), также не лишивший законной силы Брюса Эдигера (о том, как это сделать переносимо eval
), вот как это сделать nameref
в последнее время mksh
(и AT & T ksh93, за исключением - как прокомментировал @Gilles - namerefs не может ссылаться на позиционные параметры в AT & T ksh, только на именованные параметры):
#!/bin/mksh
set -- $(iostat)
nameref myvar=6
echo $myvar
Добавлен --
после set
для улучшения сопротивляемости тоже.
typeset: 6: invalid variable name
).
Некоторое время не использовал ни 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
Я нахожу меньшие куски намного легче в обращении. Вы можете или не можете использовать косвенную ссылку на переменную, в зависимости от вашего кода. Знать, как это работает, все еще полезно знать. Я использую это сам.