Odczyt wejścia w bash wewnątrz pętli while

Mam skrypt Basha, który jest czymś w stylu following,

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

Ale to najwyraźniej nie daje mi właściwego wyjścia, ponieważ gdy czytam w pętli while, próbuje ona odczytać z pliku nazwa_pliku z powodu możliwego przekierowania We / Wy.

Czy jest jakiś inny sposób na zrobienie tego samego?
Author: Stormie, 2011-07-30

5 answers

Odczyt z kontrolującego urządzenia końcowego:

read input </dev/tty

Więcej informacji: http://compgroups.net/comp.unix.shell/Fixing-stdin-inside-a-redirected-loop

 85
Author: dank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-30 13:42:48

Możesz przekierować zwykłe stdin przez jednostkę 3, aby utrzymać get it wewnątrz rurociągu:

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

BTW, jeśli naprawdę używasz cat w ten sposób, zastąp go przekierowaniem, a sprawy staną się jeszcze łatwiejsze:

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

Lub możesz zamienić stdin i unit 3 w tej wersji -- odczytaj Plik z unit 3 i zostaw stdin w spokoju:

while read line <&3; do
    # read & use stdin normally inside the loop
    read input
    echo "$input"
done 3<notify-finished
 47
Author: Gordon Davisson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-14 14:54:11

Spróbuj zmienić pętlę tak:

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

Test jednostkowy:

for line in $(cat /etc/passwd); do
    read input
    echo $input;
    echo "[$line]"
done
 6
Author: dimba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-30 13:46:57

Wygląda na to, że czytasz dwa razy, odczyt wewnątrz pętli while nie jest potrzebny. Nie musisz też wywoływać komendy cat:

while read input
do
    echo $input
done < filename
 5
Author: Hai Vu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-30 13:32:50
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
 -5
Author: Munchk1n,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-22 07:47:30