एक अन्य चर "अंदर" एक चर संदर्भ का उपयोग करें


27

मुझे यकीन है कि यह अपेक्षाकृत सरल है, मुझे नहीं पता कि यह कैसे करना है।

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

मैं कुछ ऐसा करना चाहता हूं, echo ${$myvar}जिसकी मैं व्याख्या करूं ${$myvar}-> ${6}->value


4
तकनीकी शब्द परिवर्तनशील अप्रत्यक्ष है
थोर

जवाबों:


29

आप इसे कर सकते हैं eval, बिल्ट-इन कई ठीक गोले के साथ, ksh सहित:

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

ट्रिक आपके द्वारा खिलाए जाने वाले स्ट्रिंग को डबल-कोट करने के लिए है evalताकि $ myvar को "6" के साथ प्रतिस्थापित किया जा सके, और बाहरी डॉलर-चिन्ह को बैकस्लैश करने के लिए, ताकि evalएक स्ट्रिंग "$ 6" मिल जाए।

मुझे आउटपुट के लिए "% उपयोगकर्ता" मिला, लेकिन मैंने इसे मल्टी-प्रोसेसर आरएचईएल मशीन पर आज़माया।


4
आप आधिकारिक तौर पर सप्ताह के सर्वोच्च उत्कृष्ट मास्टर मास्टर हैं b / c जो कि OpenBSD 5.4 में अथाह भयानक ksh (वास्तव में pdksh) पर भी काम करता है। यदि आप var vv को उस var के मान पर सेट करना चाहते हैं जिसका नाम var vn में है , तो बस करें vv=$( eval "echo \$$vn" )। अनेक अनेक धन्यवाद!
एक्स्टनेक्स्ट

25

अप्रत्यक्ष चर संदर्भ

आधुनिक उन्नत गोले एक चर के मूल्य को संदर्भित करने की एक विधि है जिसका नाम दूसरे चर में संग्रहीत किया जाता है। दुर्भाग्य से विधि ksh, bash और zsh के बीच भिन्न होती है।

Mksh 39R39b में, आप myvarएक nameref बना सकते हैं :

typeset -n myvar=6
echo "$myvar"

यह एटीटी ksh93 में काम नहीं करता है क्योंकि यह स्थितिगत मापदंडों के लिए namerefs का समर्थन नहीं करता है। उस मामले में जहां आपके पास एक चर है जिसमें एक चर नाम है, आप इस पद्धति का उपयोग कर सकते हैं।

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

बैश ≥2.0 में, आप लिख सकते हैं

echo "${!myvar}"

Zsh में, आप लिख सकते हैं

echo ${(P)myvar}

Ksh88 और pdksh सहित पुराने गोले में, आपका एकमात्र सहारा है जब आपके पास एक चर होता है जिसमें दूसरा चर नाम होता है और इस चर के मूल्य का उपयोग करना चाहते हैं eval, जैसा कि ब्रूस एडिगर द्वारा समझाया गया है । यह समाधान किसी भी बॉर्न / पोसिक्स शेल में काम करता है।

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

एक सरणी का उपयोग करना

यह यहां की सबसे अच्छी विधि है: यह सरल और अधिक पोर्टेबल है।

अपने उपयोग के मामले में, किसी भी शेल में सरणियों (सभी ksh वेरिएंट, बैश ≥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 39R39b, bash and2.0 और zsh में, आप एरो असाइनमेंट सिंटैक्स का उपयोग कर सकते हैं:

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

वाह, आपका 'बॉर्न / पॉसिक्स' समाधान भी ओपनबीएसडी 5.4 के ksh / pdksh में काम करता है। ऊपर ब्रूस एडगर के जवाब में मेरी टिप्पणी में इसे उदाहरण के लिए लागू करने के लिए, बस करो eval "vv=\${$vn}"। मर्सी बीकाउप, दयालु महोदय।
एक्स्टनेक्स्ट

1

जैसा कि गाइल्स (जो bashउत्तर का हिस्सा प्रदान करते हैं ) द्वारा इंगित किया गया है , ब्रूस एडगर के (यह कैसे करना है, इसे कैसे करना है eval) को अमान्य नहीं करना है , namerefहाल के दिनों में mksh(और एटी एंड टी ksh93 के साथ यह कैसे करना है , को छोड़कर - जैसे कि गिगल्स ने टिप्पणी की - namerefs AT & T ksh में स्थितीय मापदंडों का उल्लेख नहीं कर सकते हैं, केवल नामित मापदंडों के लिए):

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

सुधार प्रतिरोध के लिए, के --बाद भी जोड़ा गया set


Ksh 93u के रूप में, namerefs स्थिति संबंधी मापदंडों ( typeset: 6: invalid variable name) का संदर्भ नहीं दे सकते हैं ।
गिल्स एसओ- बुराई को रोकना '

0

सरणियों का एक और उपयोग

कुछ समय के लिए 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

मुझे छोटे चूजों को संभालना बहुत आसान लगता है। आपको अपने कोड के आधार पर अप्रत्यक्ष चर संदर्भ का उपयोग करने या करने की आवश्यकता नहीं हो सकती है। यह जानना कि यह कैसे काम करता है, यह जानना अभी भी एक अच्छी बात है। मैं खुद इसका इस्तेमाल करता हूं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.