it-swarm-eu.dev

Použijte odkaz na proměnnou „uvnitř“ jiné proměnné

Jsem si jist, že je to relativně jednoduché, prostě nevím, jak to udělat.

#!/usr/bin/ksh
set `iostat`
myvar=6

Chci něco jako echo ${$myvar} které chci interpretovat jako ${$myvar} -> ${6} -> value

28
Brandon Kreisel

Můžete to udělat pomocí eval, vestavěného do mnoha jemných granátů, včetně ksh:

#!/usr/bin/ksh
set $(iostat)
myvar=6
eval "echo \${$myvar}"

Trik spočívá v tom, že řetězec, který nakrmujete, do dvojitého uvozovky eval tak, aby byl $ myvar nahrazen "6", a zpětné lomítko vnější znak dolaru, takže eval dostane řetězec " 6 $ “.

Pro výstup jsem dostal "% user", ale zkusil jsem to na víceprocesorovém RHEL stroji.

30
Bruce Ediger

Nepřímý odkaz na proměnnou

Moderní pokročilé shelly mají metodu odkazování na hodnotu proměnné, jejíž jméno je uloženo v jiné proměnné. Metoda se bohužel liší mezi ksh, bash a zsh.

V mksh ≥R39b můžete nastavit myvar jako jméno:

typeset -n myvar=6
echo "$myvar"

Toto nefunguje v ATT ksh93, protože nepodporuje namerefs k pozičním parametrům. V případě, že máte proměnnou obsahující název proměnné, můžete tuto metodu použít.

foo=bar
typeset -n myvar=foo
echo "$myvar"  # prints bar

V bashu ≥ 2,0 můžete psát

echo "${!myvar}"

V zsh můžete psát

echo ${(P)myvar}

Ve starších skořápkách, včetně ksh88 a pdksh, vaše jediné použití, když máte proměnnou obsahující jiný název proměnné a chcete použít hodnotu této proměnné eval, jak vysvětluje Bruce Ediger . Toto řešení funguje v každém prostředí Bourne/POSIX Shell.

eval "value=\${$myvar}"
echo "$value"

Pomocí pole

Toto je nejlepší metoda: je to jednodušší a přenosnější.

Pro váš případ použití můžete v libovolném prostředí s poli (všechny varianty ksh, bash ≥ 2,0, zsh) přiřadit proměnné pole a vzít si požadovaný prvek. Dejte si pozor, aby pole ksh a bash začala číslovat na 0, ale zsh začíná na 1, pokud nevydáte setopt ksh_arrays nebo emulate ksh.

set -A iostat -- $(iostat)
echo "${iostat[5]}"

Pokud chcete zkopírovat polohové parametry do proměnné pole a:

set -A a -- "[email protected]"

V ksh93, mksh ≥R39b, bash ≥2.0 a zsh můžete použít syntaxi přiřazení pole:

iostat=($(iostat))
echo "${iostat[5]}"

Jak uvádí Gilles (který poskytl část odpovědi bash) a nezruší ani platnost Bruce Ediger's (o tom, jak to provést přenosně pomocí eval), zde je návod, jak to provést pomocí nameref v nedávné mksh (a AT&T ksh93, s výjimkou - jak @Gilles komentoval - namerefs nemohou odkazovat na polohové parametry v AT&T ksh, pouze na pojmenované parametry):

#!/bin/mksh
set -- $(iostat)
nameref myvar=6
echo $myvar

Přidáno -- po set pro lepší odolnost.

1
mirabilos

Další použití polí

Nepoužívali jsme ksh ani nějakou variantu nějakou dobu, takže si nejsem jistý, zda ksh (nebo bash) má podobnou schopnost. Moje primární Shell je zsh. Při zpracování výstupu z příkazů jako iostat používám pole, protože produkují více řádků a ne všechny řádky mají stejný formát/délku.

#! /bin/zsh
IOStatOutput=("${(@f)$(iostat)}") # Produces one element per line

Výše uvedené také obchází použití pozičních parametrů. Nyní, pokud chcete generovat, řekněme, řadu zařízení:

for Element in {7..${#IOStatOutput}} # Devices listed in elements 7 thru the last
do
    DevList+=( ${${=IOStatOutput[Element]}[1]} )
done

S menšími kousky se mi mnohem snadněji manipuluje. V závislosti na vašem kódu můžete nebo nemusíte použít nepřímý odkaz na proměnné. Vědět, jak to funguje, je stále dobré vědět. Používám to sám.

0
Friartek