Я впевнений, що це досить просто, я просто не знаю, як це зробити.
#!/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, оскільки він не підтримує namerefs до позиційних параметрів. У випадку, коли у вас є змінна, що містить ім'я змінної, ви можете використовувати цей метод.
foo=bar
typeset -n myvar=foo
echo "$myvar" # prints bar
В bash ≥2.0 ви можете писати
echo "${!myvar}"
В zsh можна писати
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 beaupoup, добрий сер.
Як вказував Жилл (який надав 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
Я знаходжу більш дрібні шматки набагато простішими в обробці. Можливо, вам не знадобиться використовувати непрямі посилання на змінну залежно від вашого коду. Знати, як це працює, все-таки добре знати. Я цим самим користуюся.