লুপ চলাকালীন কীভাবে কোনও ব্যাশে ইনপুটটি পাইপ করা যায় এবং লুপ শেষ হওয়ার পরে ভেরিয়েবলগুলি সংরক্ষণ করা যায়


88

ব্যাশ ব্যবহার করতে দেয়: cat <(echo "$FILECONTENT")

বাশও ব্যবহার করতে দেয়: while read i; do echo $i; done </etc/passwd

পূর্ববর্তী দুটি একত্রিত করতে এটি ব্যবহার করা যেতে পারে: echo $FILECONTENT | while read i; do echo $i; done

শেষের সমস্যাটি হ'ল এটি উপ-শেল তৈরি করে এবং লুপ শেষ হওয়ার পরে ভেরিয়েবলটি iআর অ্যাক্সেস করা যায় না।

আমার প্রশ্নটি হ'ল:

এই জাতীয় কিছু অর্জন কীভাবে: while read i; do echo $i; done <(echo "$FILECONTENT")বা অন্য কথায়: আমি কীভাবে নিশ্চিত হতে পারি যে iলুপের সময় বেঁচে আছে?

দয়া করে নোট করুন যে বিবৃতি দেওয়ার সময় আমি ঘেরে আছি সম্পর্কে অবগত {}তবে এটি সমস্যার সমাধান করে না (ধারণা করুন যে আপনি ফাংশনটিতে লুপটি ব্যবহার করতে চান এবং iপরিবর্তনশীলটি ফেরত চান )



সম্পর্কিত: স্ট্যাকওভারফ্লো . com / প্রশ্নগুলি / 37229058/… । নীচে উল্লিখিত প্রক্রিয়া প্রতিস্থাপন এবং lastpipeএবং তাদের উপকারিতা এবং কনস সহ সমস্ত বিকল্প ব্যাখ্যা করে ।
ivan_pozdeev

উত্তর:


117

প্রক্রিয়া প্রতিস্থাপনের জন্য সঠিক স্বরলিপিটি হ'ল:

while read i; do echo $i; done < <(echo "$FILECONTENT")

iলুপে নির্ধারিত শেষের মানটি তখন লুপটি শেষ হয়ে যায়। একটি বিকল্প হ'ল:

echo $FILECONTENT | 
{
while read i; do echo $i; done
...do other things using $i here...
}

ধনুর্বন্ধনী একটি আই / ও গ্রুপিং অপারেশন এবং তারা নিজেরাই একটি সাব-শেল তৈরি করে না। এ প্রসঙ্গে তারা একটি পাইপলাইন অংশ এবং সেই কারণে একটি subshell হিসাবে চালানো হয়, কিন্তু কারণ হল |, না { ... }। আপনি প্রশ্নের মধ্যে এটি উল্লেখ। আফাইক, আপনি কোনও ফাংশনের অভ্যন্তরে এগুলি থেকে ফিরে আসতে পারেন।


বাশ shoptবিল্টিনও সরবরাহ করে এবং এর অনেকগুলি বিকল্পগুলির মধ্যে একটি:

lastpipe

যদি সেট করা থাকে এবং জব নিয়ন্ত্রণ সক্রিয় না থাকে, শেলটি বর্তমান শেল পরিবেশে পটভূমিতে কার্যকর করা হয়নি এমন পাইপলাইনের শেষ কমান্ডটি চালায়।

সুতরাং, স্ক্রিপ্টে এর মতো কিছু ব্যবহার করা sumলুপের পরে সংশোধিতকে উপলব্ধ করে:

FILECONTENT="12 Name
13 Number
14 Information"
shopt -s lastpipe   # Comment this out to see the alternative behaviour
sum=0
echo "$FILECONTENT" |
while read number name; do ((sum+=$number)); done
echo $sum

কমান্ড লাইনে এটি করা সাধারণত 'জব নিয়ন্ত্রণ সক্রিয় নয়' (অর্থাত্ কমান্ড লাইনে, কাজের নিয়ন্ত্রণ সক্রিয়) বাজে চালায়। স্ক্রিপ্ট ব্যবহার না করে এটি পরীক্ষা করা ব্যর্থ।

এছাড়াও, তার উত্তরে গ্যারেথ রিস দ্বারা উল্লিখিত হিসাবে আপনি কখনও কখনও এখানে স্ট্রিং ব্যবহার করতে পারেন :

while read i; do echo $i; done <<< "$FILECONTENT"

এটির প্রয়োজন হয় না shopt; আপনি এটি ব্যবহার করে কোনও প্রক্রিয়া সংরক্ষণ করতে সক্ষম হতে পারেন।


আমার অজ্ঞতা ক্ষমা করুন। আমি জানি এটি সঠিক সমাধান এবং আমি এটি উত্তর হিসাবে চিহ্নিত করেছি যাতে এটি আমার পক্ষে কাজ করে। তবে এখন যখন আমি চালাব while read i; do echo $i; done < <(cat /etc/passwd); echo $iএটি শেষবারের লাইনে দুবার ফিরে আসেনি। আমি কী ভুল করছি?
ওয়াকান টানকা

@ ওয়াকানট্যাঙ্কা: আমাকে কিছুটা পরীক্ষা-নিরীক্ষা করতে হয়েছিল ... আমি বিশ্বাস করি এর উত্তর হ'ল ব্যর্থ পঠন iশূন্যের সাথে পুনরায় সেট করে, সুতরাং লুপের পরে প্রতিধ্বনি একটি ফাঁকা রেখা প্রতিধ্বনিত করে।
জোনাথন লেফলার

4
প্রক্রিয়া সাবস্টিটিউশন রেফারেন্সের জন্য কুদোস। আমি অজান্ত ছিলাম।
এটকোল্ড

@ ওয়াকান টানকা: আপনার মতো একই ফলাফল পেয়েছি, আমি while read i; do x=$i; done < <(cat /etc/passwd); echo i=$i; echo x=$xকাজ করেছি, // সম্ভবত সেই দিনগুলিতে বাশের আচরণ বদলেছে?
ইউরেনচেন

আপনি জীবন রক্ষাকারী! অনুরূপ সমাধানের জন্য ঘন্টা খোঁজা হয়েছে। আপনার একাই কাজ করেছেন।
প্যাট

28

জনাথন লেফলার প্রক্রিয়া প্রতিস্থাপন ব্যবহার করে যা করতে চান তা কীভাবে ব্যাখ্যা করবেন তবে অন্য সম্ভাবনাটি এখানে স্ট্রিংটি ব্যবহার করা :

while read i; do echo "$i"; done <<<"$FILECONTENT"

এটি একটি প্রক্রিয়া সংরক্ষণ করে।


0

এই ফাংশনটি নকল করে তোলে $ NUM বার jpg ফাইলের (ব্যাশ)

function makeDups() {
NUM=$1
echo "Making $1 duplicates for $(ls -1 *.jpg|wc -l) files"
ls -1 *.jpg|sort|while read f
do
  COUNT=0
  while [ "$COUNT" -le "$NUM" ]
  do
    cp $f ${f//sm/${COUNT}sm}
    ((COUNT++))
  done
done
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.