2013-06-19 3 views
10

के लिए बैश में चर का उपयोग कैसे करें लूप के लिए बैश में कोई चर का उपयोग कैसे करता है? अगर मैं सिर्फ पाश के लिए एक मानक का उपयोग करें, यह मैं क्या उम्मीदलूप

for i in {0..3} 
do 
    echo "do some stuff $i" 
done 

यह ठीक काम करता है नहीं करता है। यह 4 गुना, 0 से 3 समावेशी, मेरे संदेश को प्रिंट करने और अंत में गिनती डालने के माध्यम से loops।

do some stuff 0 
do some stuff 1 
do some stuff 2 
do some stuff 3 

जब मैं पाश के लिए निम्नलिखित के साथ एक ही बात की कोशिश, यह एक स्ट्रिंग के बराबर करने, जो कि मैं क्या नहीं करना चाहता है।

length=3 
for i in {0..$length} 
do 
    echo "do something right $i" 
done 

उत्पादन:

do something right {0..3} 

मैं

for i in {0.."$length"} and for i in {0..${length}} (both output was {0..3}) 

और

for i in {0..'$length'} (output was {0..$length}) 

की कोशिश की है और वे दोनों मैं क्या जरूरत नहीं करते हैं। उम्मीद है कि कोई मेरी मदद कर सकता है। लूप के लिए किसी भी बाश विशेषज्ञ की मदद के लिए अग्रिम धन्यवाद।

उत्तर

12

एक तरह से eval उपयोग कर रहा है:

for i in $(eval echo {0..$length}) 
do 
     echo "do something right $i" 
done 

नोट जब आप सेट length=;ls या length=; rm * (हालांकि उनसे प्रयास न करें) क्या होता है।

सुरक्षित रूप से, seq का उपयोग कर:

for i in $(seq 0 $length) 
do 
     echo "do something right $i" 
done 

या आप पाश के लिए सी शैली है, जो भी सुरक्षित है का उपयोग कर सकते हैं:

for ((i = 0; i <= $length; i++)) 
do 
     echo "do something right $i" 
done 
+3

+1 'eval' के प्रशंसक नहीं है, लेकिन इस तरह के उत्तर में आप विभिन्न विकल्पों को पसंद करते हैं। –

+1

सी-स्टाइल लूप स्पष्ट रूप से सबसे अच्छा विकल्प है। –

4

बैश में, ब्रेस विस्तार पहला है चरण का प्रयास किया गया, उस समय, $length प्रतिस्थापित नहीं किया गया होगा।

बैश राज्यों स्पष्ट रूप से के लिए मैनपेज:

एक अनुक्रम अभिव्यक्ति रूप ले लेता है {x..y [.. incr]}, x और y या तो पूर्णांक या एकल वर्ण हैं जहां ...

संभावनाओं की एक संख्या में इस तरह का उपयोग कर के रूप में, कर रहे हैं:

pax> for i in $(seq 0 $length) ; do echo $i ; done 
0 
1 
2 
3 

कि हालांकि आप एक बड़े कमांड लाइन दे सकता है अगर length भारी है।

एक अन्य विकल्प सी की तरह सिंटैक्स का उपयोग करने के लिए है:

pax> for ((i = 0; i <= $length; i++)) ; do echo $i; done 
0 
1 
2 
3 
3

ब्रेस subtitutions किसी अन्य से पहले प्रदर्शन कर रहे हैं, तो आप seq तरह eval या एक तीसरी पार्टी उपकरण का उपयोग करने की जरूरत है। eval के लिए

उदाहरण:

for i in `eval echo {0..$length}`; do echo $i; done 

यह जानकारी वास्तव में man bash में पाया जा सकता:

एक अनुक्रम अभिव्यक्ति रूप ले लेता है {x..y [.. incr]}, जहां एक्स और वाई या तो पूर्णांक या एकल वर्ण हैं, और एक वैकल्पिक वृद्धि, incr, एक पूर्णांक है। [...]

ब्रेस विस्तार किसी अन्य विस्तार से पहले किया जाता है, और किसी भी विशेष अन्य विस्तार करने के लिए पात्रों के परिणाम में संरक्षित कर रहे हैं। यह कड़ाई से पाठ्यचर्या है। बैश विस्तार या ब्रेसिज़ के बीच के पाठ के संदर्भ में किसी भी वाक्य रचनात्मक व्याख्या को लागू नहीं करता है।