Başka bir değişkenin "içinde" değişken bir referans kullanın


27

Oldukça basit olduğundan eminim, nasıl yapacağımı bilmiyorum.

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

Gibi echo ${$myvar}yorumlanmasını istediğim bir şey istiyorum ${$myvar}-> ${6}->value


4
Teknik terim değişken dolaylı bir terimdir .
Thor

Yanıtlar:


29

Bunu, evalksh dahil birçok ince mermiye yerleşik olarak yapabilirsiniz :

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

İşin püf noktası eval, $ myvar'ın "6" ile ikame edilmesi için beslediğiniz dizgiyi iki kez alıntılamak ve dış dolar işaretini ters eğmek, böylece eval"$ 6" dizesini almaktır.

Çıktı için "% user" aldım ancak çok işlemcili bir RHEL makinesinde denedim.


4
Resmi olarak, OpenBSD 5.4'teki aşılmaz derecede korkunç ksh (gerçekten pdksh) üzerinde çalışan b / c haftasındaki Yüce Müthiş Büyük Usta'sınız. Var vv'yi , adı var vn içinde bulunan var değerine ayarlamak istiyorsanız , sadece yapın vv=$( eval "echo \$$vn" ). Bir ton teşekkürler!
execNext

25

Dolaylı değişken referansı

Modern gelişmiş mermiler, adı başka bir değişkende saklanan bir değişkenin değerini referans alma yöntemine sahiptir. Ne yazık ki, yöntem ksh, bash ve zsh arasında değişir.

Mksh ≥R39b'de, myvarbir ad yapabilir :

typeset -n myvar=6
echo "$myvar"

Bu, ATT ksh93'te çalışmaz çünkü konum parametrelerinin isimlerini desteklemez. Bir değişken ismi içeren bir değişkeniniz olması durumunda, bu yöntemi kullanabilirsiniz.

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

Bash .02.0, yazabilirsiniz

echo "${!myvar}"

Zsh ile yazabilirsiniz

echo ${(P)myvar}

Başka bir değişken adını içeren bir değişken var ve bu değişkenin değerini kullanmak istediğinizde ksh88 ve pdksh, bunun tek yolu da dahil olmak üzere eski kabukları, içinde eval, Bruce Ediger tarafından açıklandığı gibi . Bu çözüm herhangi bir Bourne / POSIX kabuğunda çalışır.

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

Bir dizi kullanma

Buradaki en iyi yöntem: basit ve daha taşınabilir.

Kullanım durumunuz için, dizileri olan herhangi bir kabukta (tüm ksh değişkenleri, bash ≥2.0, zsh), bir dizi değişkenine atayabilir ve istediğiniz öğeyi alabilirsiniz. O ksh sakının ve bash diziler 0'dan numaralandırma başlamak, ancak 1 de zsh tekrar başlıyorsa sorunu olmadıkça setopt ksh_arraysveya emulate ksh.

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

Konumsal parametreleri bir dizi değişkenine kopyalamak istiyorsanız a:

set -A a -- "$@"

Ksh93, mksh ≥R39b, bash ≥2.0 ve zsh, dizi atama sözdizimini kullanabilirsiniz:

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

Vay, 'Bourne / POSIX' çözümünüz OpenBSD 5.4'ün ksh / pdksh'inde de çalışıyor. Bruce Ediger'in yukarıdaki cevabına yaptığı yorumumdaki örneğe uygulamak için, sadece yapın eval "vv=\${$vn}". Merci Beaucoup, kibar efendim.
execNext

1

Gilles ( bashcevabın bir kısmını sağlayan) tarafından belirtildiği gibi, Bruce Ediger'in (taşınabilir bir şekilde nasıl yapılacağı ile ilgili eval) geçersiz kılınmadığı gibi, işte namerefson zamanlarda mksh(ve @Gilles'in yorumladığı gibi - ve AT&T ksh93) - AT&T ksh içindeki konumsal parametrelere, yalnızca adlandırılmış parametrelere atıfta bulunamaz):

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

Gelişmiş direnç için de --sonra eklendi set.


Ksh 93u'dan itibaren isimler konumsal parametrelere ( typeset: 6: invalid variable name) başvuramazlar .
Gilles 'SO- kötülük yapmayı bırak'

0

Dizilerin başka bir kullanımı

Bir süredir ksh veya herhangi bir değişkeni kullanmadım, bu nedenle ksh (veya bash) 'nin benzer bir yeteneği olup olmadığından emin değilim. Birincil kabuğum zsh. Birden çok satır ürettikleri için iostat gibi komutlardan gelen çıktıları işlerken dizileri kullanıyorum , tüm satırlar aynı format / uzunlukta değil.

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

Yukarıdakiler ayrıca konumsal parametrelerin kullanımını atlar. Şimdi, eğer bir dizi cihaz üretmek istiyorsan:

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

Daha küçük parçaların kullanımı daha kolay buluyorum. Kodunuza bağlı olarak dolaylı değişken referansı kullanmanız gerekebilir veya gerekmeyebilir. Nasıl çalıştığını bilmek hala bilmek iyi bir şey. Ben kendim kullanırım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.