Bash while цикл, который читает файл по строкам

Существует два способа чтения строки в строке, которую я хочу обсудить здесь:

#!/bin/bash    

while read line    
do    
    echo-e "$ line \ n"    
done <file.txt

и

#!/bin/bash    
exec 3<file.txt

while read line    
do    
    echo-e "$ line \ n"    
done

Итак, первая версия отлично работает, но я не понимаю механизм работы while с файлом. Но механизм второй версии я понимаю. Но здесь я не понимаю, почему он висит и ничего не печатает.

Ответ 1

Первый цикл работает, потому что перенаправление после done применяется ко всему циклу, поэтому read есть чтение из файла, а не со стандартного ввода script.

Вторая версия зависает, потому что read читает из дескриптора файла 0, который является стандартным вводом, и вы ничего там не набрали. Строка exec перенаправляет дескриптор файла 3 для чтения из файла, но вы не читаете его из файлового дескриптора 3.

Вы можете спасти второй, используя:

exec <file.txt

Теперь стандартный файл считывается из именованного файла.

Ответ 2

Это может сработать для вас:

exec 3<file.txt

while read -u3 line
do
    echo -e "$line \n"
done

-u3 читается из дескриптора файла 3

Странно, что echo не имеет ключа дополнения, например команды ksh print.

Ответ 3

В ваших скриптах мало ошибок.

  • Пробел между $ и именем переменной. (может быть плохое редактирование)
  • Пробел между echo и -e. (может быть плохое редактирование)
  • Упоминание чтения в файловом дескрипторе, где файл открыт. Вы читаете файл в дескрипторе 0, а exec работает в дескрипторе 3.

Это должно быть что-то вроде этого -

#!/bin/bash    
exec 3<file.txt

while read line  
do
    echo -e "$line \n"
done <&3

Ответ 4

-u3 отлично подходит для моей цели (читая только следующую строку)

#!/bin/bash

logs=(*Logs.txt)
[[ -e "${logs[0]}" ]] || exit 0

exec 3<"${logs[0]}"

while read -u3 line
do
        if [[ $(echo "$line"| grep -c SCSI_STATUS_CHECK_CONDITION) -eq 1 ]]; then
                read -u3 line
                echo "$line"
        fi
done