Почему перенаправление на цикл 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
в петлю.