Почему перенаправление на цикл while не печатает сообщения?

Вот код оболочки, используемый для отслеживания изменений в файле и вывода содержимого на терминал:

while read LINE
do
  echo $LINE
done < `tail -f /var/log/messages`

Это не работает, почему?

2 ответа

Решение

Нет необходимости в цикле while. Вы пытаетесь сделать два раза то же самое. Также файл /var/log/messages нет в Ubuntu больше.

Просто используйте:

tail -f /var/log/syslog

отслеживать новый контент, который добавляется в конце текстового файла. Если что-то новое написано до конца /var/log/syslog он распечатывается на вашем терминале.

Изменить: почему команда в вопросе не работает:

Во-первых, конечно, /var/log/messages не существует. Но если она существует, команда между обратными галочками выполняется и заменяется ее выводом (за исключением завершающих символов новой строки). Так что выход tail -f ... будет использоваться в качестве имени файла для перенаправления ввода <, То, что вы, вероятно, хотите, выглядело бы следующим образом (<(...) Перенаправление):

while read LINE; do
  echo $LINE
done < <(tail -f /var/log/messages)

<(...) перенаправление создает именованный канал, где на одном конце команда tail -f пишет в. На другом конце while цикл читает содержимое построчно. Именованный канал ведет себя скорее всего к обычному файлу. Это просто кусок соединения между двумя командами. Кстати, | делает то же самое, но эти каналы не имеют имен, они являются каналами по умолчанию: 0 -> stdin, 1 -> stdout и 2 -> stderr.

От bash страница руководства:

 Process substitution is supported on systems that support named pipes (FIFOs) or the 
 /dev/fd method of naming open files. It takes the form of <(list) or >(list).  

Обычный портативный способ сделать это:

tail -f /var/log/messages | while read LINE
do
  echo $LINE
done

Ответ @chaos использует синтаксис замены процесса, который встречается только в расширенных оболочках, таких как zsh а также bash, Вы не должны полагаться на их функции, если вам когда-нибудь понадобится запустить скрипт на другом компьютере.

Конечно, я предполагаю, что вы хотите поставить что-то более сложное, чем echo $LINE в петлю.

Другие вопросы по тегам