একটি লুপের মধ্যে ব্যবহারকারীর ইনপুট পড়ুন


103

আমার একটি বাশ স্ক্রিপ্ট রয়েছে যা অনুসরণ করার মতো কিছু,

cat filename | while read line
do
    read input;
    echo $input;
done

তবে এটি স্পষ্টতই আমাকে সঠিক আউটপুট দিচ্ছে না যখন আমি যখন লুপটি পড়ি তখন এটি সম্ভাব্য I / O পুনঃনির্দেশের কারণে ফাইলের ফাইল নাম থেকে পড়ার চেষ্টা করে।

একই কাজ করার অন্য কোনও উপায়?


একই জিনিস ঘটে যখন আপনি
ব্যাশে

উত্তর:


108

নিয়ন্ত্রণকারী টার্মিনাল ডিভাইস থেকে পড়ুন:

read input </dev/tty

আরো তথ্য: http://compgroups.net/comp.unix.shell/Fixing-stdin-inside-a-redirected-loop


12
-1, যেহেতু এটি অন্য কোনও পুনঃনির্দেশকে বাধা দেবে। উদাহরণস্বরূপ, bash yourscript < /foo/barব্যবহারকারীর ইনপুটটির জন্য অপেক্ষা করবেন, পাসওয়ার্ড পড়ার সময় এটি গ্রহণযোগ্য। @ গর্ডন ডেভিসনের উত্তরটি অন্যান্য সমস্ত ব্যবহারের পক্ষে পছন্দনীয়।
tiwo

57

পাইপলাইনের ভিতরে রাখার জন্য আপনি নিয়মিত স্টিডিনটি ইউনিট 3 এর মাধ্যমে পুনর্নির্দেশ করতে পারেন:

{ cat notify-finished | while read line; do
    read -u 3 input
    echo "$input"
done; } 3<&0

বিটিডাব্লু, আপনি যদি সত্যিই catএইভাবে ব্যবহার করছেন তবে এটিকে পুনর্নির্দেশের সাথে প্রতিস্থাপন করুন এবং জিনিসগুলি আরও সহজ হয়ে উঠবে:

while read line; do
    read -u 3 input
    echo "$input"
done 3<&0 <notify-finished

অথবা, আপনি সেই সংস্করণে স্টিডিন এবং ইউনিট 3 অদলবদল করতে পারেন - ইউনিট 3 দিয়ে ফাইলটি পড়ুন, এবং কেবল স্টিডিনকে একা ছেড়ে যান:

while read line <&3; do
    # read & use stdin normally inside the loop
    read input
    echo "$input"
done 3<notify-finished

আপনার দ্বিতীয় স্ক্রিপ্টটি কেন ঝুলছে?
লুকা বোররিওন

4
@ লুকাবোরিওন: আপনি কীভাবে এটি ব্যবহার করছেন? আপনি কি এটির ইনপুট দেওয়ার জন্য অপেক্ষা করছেন (নোটটি যা read lineবিজ্ঞপ্তি থেকে পড়া হচ্ছে, তবে আপনি যদি read -u 3 inputএটি কনসোল থেকে লিখিতভাবে লিখিতভাবে চালিত হন )?
গর্ডন ডেভিসন

3

দেখে মনে হচ্ছে আপনি দুবার পড়েছেন, কিছুক্ষণের মধ্যে পড়ার সময় লুপের দরকার নেই। এছাড়াও, আপনার বিড়াল কমান্ডটি চালানোর দরকার নেই:

while read input
do
    echo $input
done < filename

4
ওপির লক্ষ্যটি ব্যবহারকারীটির কাছ থেকে আসা লুপের অভ্যন্তরে পড়ার জন্য, অন্যদিকে বাইরেরটি ফাইলটি থেকে পড়া। সুতরাং, তারা বৈধভাবে দুটি ভিন্ন উত্স থেকে দুটি পৃথক পাঠ চান। এটি প্রশ্নের পাঠ্য (অভ্যন্তরের readআচরণকে "ঠিক নয় [কারণ] এটি ফাইল থেকে পড়ার চেষ্টা করে filename" হিসাবে বর্ণনা করা) এবং তাদের গৃহীত উত্তর উভয় থেকেই পরিষ্কার is
চার্লস ডাফি 16

3

লুপটি এভাবে পরিবর্তন করার চেষ্টা করুন:

for line in $(cat filename); do
    read input
    echo $input;
done

ইউনিট পরীক্ষা:

for line in $(cat /etc/passwd); do
    read input
    echo $input;
    echo "[$line]"
done

@ w2lame আবার পরীক্ষিত, "লুপ" করার জন্য "লুপ" করার জন্য "আমার জন্য কাজ করে" পরিবর্তন করুন। "সেক্স-এক্স" চেষ্টা করে দেখুন ত্রুটিটি কোথা থেকে এসেছে
ডিম্বা

4
বিড়াল ব্যবহার করবেন না, হাই ভু-র উত্তর দেখুন
ফ্রেডরিক পিহল

+1 অন্যান্য পরামর্শের চেয়ে আমার নির্দিষ্ট প্রয়োজনের জন্য এটি প্রয়োগ করা অনেক সহজ ছিল।
নাথান ওয়ালেস


1

আমি এই পরামিতিটি খুঁজে পেয়েছি u

"-উ 1" এর অর্থ "স্টিডিন থেকে পড়া"

while read -r newline; do
    ((i++))
    read -u 1 -p "Doing $i""th file, called $newline. Write your answer and press Enter!"
    echo "Processing $newline with $REPLY" # united input from two different read commands.
done <<< $(ls)

-6
echo "Enter the Programs you want to run:"
> ${PROGRAM_LIST}
while read PROGRAM_ENTRY
do
   if [ ! -s ${PROGRAM_ENTRY} ]
   then
      echo ${PROGRAM_ENTRY} >> ${PROGRAM_LIST}
   else
      break
   fi
done
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.