बैश डायनामिक (परिवर्तनशील) चर नाम


12

मैं गतिशील रूप से तत्वों की एक सरणी में हेरफेर करके कुछ अंकगणितीय प्रक्रिया बनाना चाहता हूं।

for name in FIRST SECOND THIRD FOURTH FIFTH; do
    $name = $(( $6 + 1 ))
    $name = "${$name}q;d"
    echo "${$name}"; printf "\n"
done

इच्छा परिणाम $6बराबरी के लिए नीचे होगा 0

1q;d
2q;d
3q;d
4q;d
5q;d

लेकिन मुझे यह त्रुटि मिलती है

reel_first_part.sh: line 18: FIRST: command not found
reel_first_part.sh: line 19: ${$name}q;d: bad substitution
reel_first_part.sh: line 18: FIRST: command not found
reel_first_part.sh: line 19: ${$name}q;d: bad substitution
reel_first_part.sh: line 18: FIRST: command not found
reel_first_part.sh: line 19: ${$name}q;d: bad substitution

मुझे लगता है कि यह कुछ आसान है। जब मैं कुछ ऐसा करता था तो यह काम करता था

FIRST=$(( $6 + 1 ))
FIRST="${FIRST}q;d"

1
क्या आप इसे बेहतर तरीके से समझा सकते हैं। वास्तव में समझ में नहीं आता कि आप क्या करने की कोशिश कर रहे हैं।
न्यूरॉन

`$ नाम = $ (($ 6 + 1))` क्या करना है?
PSkocik

@ पीस्कोकिक मैं करने की उम्मीद कर रहा थाFIRST=$(( $6 + 1 ))
जिआनीस क्रिस्तोफिस

जवाबों:


16

सबसे पहले =चर घोषणा में चारों ओर कोई स्थान नहीं हो सकता है bash

आप जो चाहते हैं उसे पाने के लिए उपयोग कर सकते हैं eval

उदाहरण के लिए आपकी तरह एक नमूना स्क्रिप्ट:

#!/bin/bash
i=0
for name in FIRST SECOND THIRD FOURTH FIFTH; do
    eval "$name"="'$(( $i + 1 ))q;d'"
    printf '%s\n' "${!name}"
    i=$(( $i + 1 ))
done

प्रिंट:

1q;d
2q;d
3q;d
4q;d
5q;d

evalसावधानी से उपयोग करें , कुछ लोग इसे किसी वैध कारण से बुराई कहते हैं।

declare काम भी करेगा:

#!/bin/bash
i=0
for name in FIRST SECOND THIRD FOURTH FIFTH; do
    declare "$name"="$(( $i + 1 ))q;d"
    printf '%s\n' "${!name}"
    i=$(( $i + 1 ))
done

प्रिंट भी:

1q;d
2q;d
3q;d
4q;d
5q;d

!विस्मयादिबोधक चिह्न किसके printf '%s\n' "${!name}"लिए है?
गियान्निस क्रिस्तोफिस

1
इसकी बुलाया अप्रत्यक्ष विस्तार bashपैरामीटर expansion..read इस
heemayl

1
बैश में भी declare/ eval: के लिए एक अच्छा विकल्प है printf -v varname '%fmt' args। कुछ बैश-पूरा आंतरिक कार्य कॉल-बाय-संदर्भ के लिए इसका उपयोग करते हैं। (में स्टोर करने के लिए एक चर का नाम पास)।
पीटर कॉर्ड्स

नोट: declareकेवल स्थानीय चर में चर का उपयोग करना , जबकि evalदृष्टिकोण इसे विश्व स्तर पर सेट करता है।
उपयोगकर्ता

12

यदि आप किसी अन्य वैरिएबल में संग्रहित नाम रखते हुए बैश वेरिएबल को संदर्भित करना चाहते हैं, तो आप इसे निम्नानुसार कर सकते हैं:

$ var1=hello
$ var2=var1
$ echo ${!var2}
hello

आप उस चर का नाम संग्रहीत करते हैं जिसे आप इस मामले में एक्सेस करना चाहते हैं, कहते हैं, var2। फिर आप इसे एक्सेस करते हैं ${!<varable name>}जहां <variable name>एक वैरिएबल है जिस वेरिएबल का नाम आप एक्सेस करना चाहते हैं।


साथ पोर्टेबल तरीका है, eval var=\$$holderलेकिन evalखतरनाक है!
गवेंको

1
index=0;                                                                                                                                                                                                           
for name in FIRST SECOND THIRD FOURTH FIFTH; do
    name=$(($index + 1))
    echo "${name}q;d"
    index=$((index+1))
done

क्या आप जो कोशिश कर रहे हैं?


1

मुझे आपके कोड और आपके वांछित आउटपुट से क्या मिलेगा (अगर मैं गलत हूं तो मुझे सुधारो):
"FIRST" / "सेकंड" / ... चर नामों का कोई उपयोग नहीं है, आपको बस एक सूचकांक के साथ एक लूप की आवश्यकता है .. ।

यह काम करेगा:

for i in {1..5} ; do echo $i"q;d" ; done


हां, आप सही हैं, इसके अलावा मैं एक चर के साथ एक अंकगणितीय कार्य करना चाहता हूं।
गियान्निस क्रिस्तोफिस

क्या आप इस अंकगणितीय कार्य का उदाहरण दे सकते हैं? क्या आपको इसके लिए चर नाम (जैसे "THIRD") की आवश्यकता है या सिर्फ सूचकांक मूल्य की?
सीएससी

SUM=$(($6 + $i)); echo $SUM"q;d", मैं देखता हूं कि मैं क्या गलत कर रहा था।
गियाननिस क्रिस्तोकिस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.