ব্যাশে, লুপের জন্য লুপ নিয়ন্ত্রণে কোনও পূর্ণসংখ্যের পরিবর্তনশীল ব্যবহার করা সম্ভব?


65

আমার কাছে নিম্নলিখিত বাশ স্ক্রিপ্ট রয়েছে:

#!/bin/bash

upperlim=10

for i in {0..10}
do
echo $i
done

for i in {0..$upperlim}
do
echo $i
done

প্রথম forলুপ ( লুপ নিয়ন্ত্রণে পরিবর্তনশীল ব্যতীতupperlim ) ভাল কাজ করে, তবে দ্বিতীয় forলুপ ( লুপ নিয়ন্ত্রণে ভেরিয়েবল সহupperlim ) কার্যকর হয় না। forএটির কোনও উপায় আছে যে আমি দ্বিতীয় লুপটি সংশোধন করতে পারি যাতে এটি কাজ করে? আপনার সময় জন্য ধন্যবাদ।


4
এইচএম, এমনকি for i in {0..$((upperlim))}; do echo $i; doneকাজ করে না
বনসি স্কট

এবং +1 কারণ আমি সেই আচরণটি আকর্ষণীয় মনে করি
বনসি স্কট

এর সম্ভাব্য ক্রস সাইটের সদৃশ: স্ট্যাকওভারফ্লো.
com/ জিজ্ঞাসা / ১69৯৫11/…

একটি বাহ্যিক লিঙ্ক যে এই উত্তর দেয়: cyberciti.biz/faq/...
কন Psych

উত্তর:


62

এর কারণ হ'ল আদেশটি যাতে জিনিসগুলিতে বাশ হয়। ভেরিয়েবলগুলি প্রসারিত হওয়ার আগে ব্রেস সম্প্রসারণ ঘটে । আপনার লক্ষ্যটি অর্জন করতে, আপনাকে লুপের জন্য সি-স্টাইল ব্যবহার করতে হবে:

upperlim=10

for ((i=0; i<=upperlim; i++)); do
   echo "$i"
done

1
আর জন্য কাজ করে zsh(কিন্তু না পাশাপাশি csh, tcsh)।
গণিত

29

আপনার শৈলীতে এটি বিল্ট-ইনগুলি ব্যতীত অন্য কিছু ব্যবহার করে সম্পূর্ণ করতে আপনাকে ওয়াল ব্যবহার করতে হবে:

d=12

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

তবে সাথে seq:

lowerlimit=0
upperlimit=12

for i in $(seq $lowerlimit $upperlimit)
do
echo $i
done

ব্যক্তিগতভাবে আমি seqআরও পঠনযোগ্য হতে ব্যবহারটি খুঁজে পাই ।


"বিল্ট-ইনস" এর জন্য? seqএটি একটি বাহ্যিক কমান্ড এবং বশ যেখানেই পাওয়া যায় না।
জর্ডানম

9
@ জোর্ডানম: বাশ সহ সমস্ত বিল্টিন ব্যবহার করার জন্য। তারপরে আমি বললাম "তবে সাথে seq", স্বীকৃতি দিয়েছিলাম যে এটি কোনও অন্তর্নির্মিত নয়।
Jodie সি

ব্রেস সম্প্রসারণ অন্তর্নির্মিত হয় তা এখানে সমস্যা নয়। readউদাহরণস্বরূপ একটি বিল্টিন, তবে evalএটির কোনও কারণ নেই ।
জর্ডানম

1
বিল্টিনগুলি মোটেই সমস্যাযুক্ত নয়। আমি জিজ্ঞাসাকারীর জন্য একটি সর্ব-বাশ সমাধান সরবরাহ করতে চেয়েছিলাম। আপনি যদি এই বিষয়ে তর্ক চালিয়ে যেতে চান তবে এটি চ্যাটে নিয়ে যান; মন্তব্যগুলি এই ধরণের জন্য ভাল নয়
Jodie সি

8

POSIX উপায়

আপনি যদি বহনযোগ্যতার বিষয়ে যত্নশীল হন তবে পসিক্স মান থেকে উদাহরণটি ব্যবহার করুন :

i=2
END=5
while [ $i -le $END ]; do
    echo $i
    i=$(($i+1))
done

আউটপুট:

2
3
4
5

যে জিনিসগুলি পসিক্স নয় :

  • (( ))ডলার ব্যতীত, যদিও এটি পসিক্স নিজেই উল্লিখিত একটি সাধারণ এক্সটেনশন ।
  • [[[এখানে যথেষ্ট। আরও দেখুন: https://stackoverflow.com
  • for ((;;))
  • seq
  • {start..end}, এবং এটি ব্যাশ ম্যানুয়াল অনুসারে ভেরিয়েবলগুলির সাথে কাজ করতে পারে না ।
  • let i=i+1: পজিক্স 7 2. শেল কমান্ড ভাষা শব্দটি ধারণ করে না letএবং এটি bash --posix4.3.42 এ ব্যর্থ হয়
  • ডলার i=$i+1প্রয়োজন হতে পারে, কিন্তু আমি নিশ্চিত না। পসিক্স 7 2.6.4 গাণিতিক সম্প্রসারণ বলেছেন:

    শেল ভেরিয়েবল এক্সে যদি এমন কোনও মান থাকে যা বৈধ পূর্ণসংখ্যক ধ্রুবক গঠন করে, allyচ্ছিকভাবে একটি শীর্ষস্থানীয় প্লাস বা বিয়োগ চিহ্ন সহ, তবে পাটিগণিতের বিস্তৃতি "$((x))"এবং "$(($x))"একই মানটি প্রত্যাবর্তন করে।

    তবে এটি আক্ষরিকভাবে পড়া যা বোঝায় না যে এটি $((x+1))প্রসারিত x+1হয় না কারণ এটি পরিবর্তনশীল নয়।


1

প্যারামিটার বিস্তারের আগে ব্যাশ ব্রেস-এক্সপেনশন হওয়ার পরে আপনার পদ্ধতির কাজ হবে না। আপনাকে আগে ভেরিয়েবলটি প্রসারিত করতে হবে।

আপনি eval সঙ্গে প্রায় কাজ করতে পারেন :

upperlim=10
eval '
        for i in {0..'"$upperlim"'}
        do
                echo $i
        done
'

সঙ্গে যখন লুপ :

upperlim=10
#with while
start=0
while [[ $start -le $upperlim ]]
do
    echo "$start"
    ((start = start + 1))
done

এছাড়াও আপনি এটি সেক কমান্ড দিয়ে করতে পারেন :

upperlim=10
#seq
for i in $(seq "$upperlim"); do
  echo "$i"
done

আপনি যদি চালাতে চান তবে আপনাকে for i in {0..$upperlim}কর্নশেল ব্যবহার করতে হবে। উদাহরণ:

#!/bin/ksh
upperlim=10

for i in {0..$upperlim}
do
        echo $i
done
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.