एक लूप के अंदर उपयोगकर्ता इनपुट पढ़ें


99

मेरे पास एक बैश स्क्रिप्ट है, जो कुछ इस प्रकार है,

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

लेकिन यह स्पष्ट रूप से मुझे सही आउटपुट नहीं दे रहा है क्योंकि जब मैं संभव लूप / रीडायरेक्शन की वजह से फाइल फाइलनाम से पढ़ने की कोशिश करता हूं तो लूप में पढ़ता हूं।

वही करने का कोई और तरीका?


समान बात तब होती है जब आप उपयोगकर्ता को बैश में स्विच करते हैं और स्क्रिप्ट में स्विच किए गए उपयोगकर्ता के तहत रीड कमांड चलाते हैं
क्रुपाल

जवाबों:


106

कंट्रोलिंग टर्मिनल डिवाइस से पढ़ें:

read input </dev/tty

अधिक जानकारी: http://compgroups.net/comp.unix.shell /


12
-1, क्योंकि यह किसी अन्य पुनर्निर्देशन को दरकिनार करेगा। उदाहरण के लिए, bash yourscript < /foo/barउपयोगकर्ता इनपुट की प्रतीक्षा करेगा, यह केवल पासवर्ड पढ़ने के दौरान स्वीकार्य है। @GordonDavisson द्वारा उत्तर अन्य सभी उपयोगों के लिए बेहतर है।
tiwo

56

आप पाइपलाइन के अंदर इसे प्राप्त करने के लिए यूनिट 3 के माध्यम से नियमित स्टड को पुनर्निर्देशित कर सकते हैं:

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

BTW, यदि आप वास्तव में 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

आपकी दूसरी स्क्रिप्ट क्यों लटकी है?
लुका बोर्रोन

2
@LucaBorrione: आप इसका उपयोग कैसे कर रहे हैं? क्या आप इसे इनपुट देने के लिए इंतजार कर रहे हैं (नोट जो read lineनोटिफ़िकेशन से समाप्त हो रहा है, लेकिन अगर आप इसे चलाते हैं जैसे कि लिखा हुआ read -u 3 inputकंसोल से पढ़ रहा है)?
गॉर्डन डेविसन

3

ऐसा लगता है कि आपने दो बार पढ़ा है, जबकि लूप के अंदर पढ़ने की आवश्यकता नहीं है। इसके अलावा, आपको बिल्ली कमांड को लागू करने की आवश्यकता नहीं है:

while read input
do
    echo $input
done < filename

4
ओपी का लक्ष्य उपयोगकर्ता से आने के लिए लूप के अंदर पढ़ने के लिए है, जबकि बाहरी एक फ़ाइल से पढ़ना है। इस प्रकार, वे वैध रूप से दो अलग-अलग स्रोतों से, दो अलग-अलग रीड्स चाहते हैं। यह प्रश्न के पाठ (दोनों के आंतरिक readव्यवहार को "सही नहीं है [क्योंकि] यह फ़ाइल से पढ़ने की कोशिश करता है filename") और उनके स्वीकृत उत्तर का वर्णन करने से दोनों स्पष्ट है ।
चार्ल्स डफी

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
बिल्ली का उपयोग न करें, Hai Vu से जवाब देखें
फ्रेड्रिक पीहल

+1। अन्य सुझावों की तुलना में मेरी विशिष्ट आवश्यकताओं के लिए इसे लागू करना बहुत आसान था।
नाथन वालेस

1
देखें के लिए नहीं पढ़ें लाइन्स के साथ Wooledge विकि पर। इसके अलावा, shellcheck.net चेतावनी SC2013
चार्ल्स डफी

1

मुझे यह पैरामीटर -यू पढ़ने के साथ मिला है।

"-यू 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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.