Kullanıcı girişini bir döngü içinde okuyun


103

Aşağıdaki gibi bir bash betiğim var,

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

ancak bu, while döngüsünü okuduğumda, olası G / Ç yeniden yönlendirmesi nedeniyle dosya adından okumaya çalıştığı gibi açıkça bana doğru çıktıyı vermiyor.

Aynısını yapmanın başka bir yolu var mı?


Yanıtlar:



57

Düzenli stdin'i ardışık düzen içinde tutmak için ünite 3'e yönlendirebilirsiniz:

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

BTW, gerçekten catbu şekilde kullanıyorsanız , yeniden yönlendirmeyle değiştirin ve işler daha da kolaylaşır:

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

Veya bu sürümde stdin ile birim 3'ü değiştirebilirsiniz - dosyayı 3. birim ile okuyun ve stdin'i yalnız bırakın:

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

ikinci senaryon neden asılı?
Luca Borrione

2
@LucaBorrione: Nasıl kullanıyorsun? Girdi vermenizi mi bekliyor ( read linenotify-bitmiş'ten okuyor, ancak yazıldığı gibi çalıştırırsanız read -u 3 inputkonsoldan okuyor)?
Gordon Davisson

3

Görünüşe göre iki kez okumuşsunuz, while döngüsünün içinde okumaya gerek yok. Ayrıca cat komutunu çalıştırmanıza gerek yoktur:

while read input
do
    echo $input
done < filename

4
OP'nin amacı, döngü içindeki okumanın kullanıcıdan gelmesidir, dıştaki ise dosyadan okumaktır. Bu nedenle, yasal olarak iki farklı kaynaktan iki farklı okuma istiyorlar. Bu, hem soru metninden (içerideki kişinin readdavranışını "doğru değil [çünkü] dosyadan okumaya çalışıyor" olarak tanımlayarak filename) hem de kabul ettiği cevaptan anlaşılıyor .
Charles Duffy

3

Döngüyü şu şekilde değiştirmeyi deneyin:

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

Ünite testi:

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

@ w2lame Tekrar test edildi, "döngü" için "döngü için" değiştir - benim için çalışıyor. "Sex -x" i deneyin hatanın nereden geldiğini görün
dimba

4
kedi kullanma, Hai Vu'nun cevabına bakın
Fredrik Pihl

+1. Bu benim özel ihtiyaçlarım için diğer önerilerden çok daha kolaydı.
Nathan Wallace

1
Bkz . Wooledge wiki'deki Satırları Okuma . Ayrıca shellcheck.net SC2013 uyarısı
Charles Duffy

1

Bu parametreyi -u okuyarak buldum.

"-u 1", "standarttan oku" anlamına gelir

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.