الحصول على إدخال المستخدم بعد إعادة توجيه stdin ، في نص بورن

StackOverflow https://stackoverflow.com/questions/1385380

  •  21-09-2019
  •  | 
  •  

سؤال

(هذا جزء غير مباشر من واجب منزلي أكبر بكثير)

لدي شيء مثل

    while read LINE
    do
        stuff-done-to-$LINE
        echo "Enter input:"
        read INPUT
        stuff-done-to-$INPUT
    done < infile

لا يمكنني العثور على طريقة ناجحة لاستخدام وحدة التحكم/stdin الافتراضية للقراءة الثانية ، بدلاً من stdin المعاد توجيهها.

يحتاج إلى أن يكون نص بورن النقي.

هل كانت مفيدة؟

المحلول

أعتقد أن هذا مدعوم في قذيفة بورن:

exec 3<doc.txt
while read LINE <&3
do
    stuff-done-to-$LINE
    # the next two lines could be replaced by: read -p "Enter input: " INPUT
    echo "Enter input:"
    read INPUT
    stuff-done-to-$INPUT
done < infile

يتناوب الإدخال بين الملف والمستخدم. في الواقع ، ستكون هذه طريقة رائعة لإصدار سلسلة من المطالبات من ملف.

هذا يعيد توجيه الملف "infile" إلى رقم واصف الملف 3 الذي أوله read يحصل على مدخلاتها. واصف الملف 0 stdin, ، 1 هو stdout و 2 هو stderr. يمكنك استخدام FDs الأخرى معهم.

لقد اختبرت هذا على Bash و Dash (على نظامي SH متماثل إلى Dash).

بالطبع يعمل. هذا أكثر متعة:

exec 3<doc1.txt
exec 4<doc2.txt
while read line1 <&3 && read line2 <&4
do
    echo "ONE: $line1"
    echo "TWO: $line2"
    line1=($line1) # convert to an array
    line2=($line2)
    echo "Colors: ${line1[0]} and ${line2[0]}"
done

هذا يتناوب طباعة محتويات ملفين ، وتجاهل الخطوط الإضافية لأي ملف أطول.

ONE: Red first line of doc1
TWO: Blue first line of doc2
Colors: Red and Blue
ONE: Green second line of doc1
TWO: Yellow second line of doc2
Colors: Green and Yellow

DOC1 لديه فقط سطرين. يتم التخلص من السطر الثالث والخطوط اللاحقة من DOC2.

نصائح أخرى

يمكنك قراءة/كتابة محطة المستخدم من خلال/dev/tty ، وهذا مستقل عن القذيفة التي تستخدمها وما إذا كانت stdin/stdout قد تم إعادة توجيهها ، لذلك تحتاج فقط:

echo "Enter input:" > /dev/tty
read INPUT < /dev/tty

يجب أن يعمل هذا:

for LINE in `cat infile`; do
   stuff-done-to-$LINE
   echo "Enter input:"
   read INPUT
   stuff-done-to-$INPUT
done

لا يمكنك. لا يوجد stdin الافتراضي وإعادة توجيه stdin. هناك stdin ، وما هو متصل به هو إما وحدة التحكم ، أو الملف.

الشيء الوحيد الذي يمكنك القيام به هو القيام ببعض الوقت باستخدام عداد على عدد خطوط ملفك. ثم ، استخرج كل سطر باستخدام بعض الاستخدام الذكي لـ SED أو Tail+Head. لا يمكنك استخدام while read line لأنه لن يكون لديك أي طريقة للتمييز بين القراءة من وحدة التحكم والقراءة من الملف.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top