Содержимое выходного файла при его изменении


47

Я хочу вывести содержимое файла, пока они меняются, например, если у меня есть файл, foobarи я делаю:

magic_command foobar

Текущий терминал должен отображать содержимое файла и ждать, пока я не знаю, я нажимаю ^ C.

Тогда если из другого терминала я делаю:

echo asdf >> foobar

Первый терминал должен отображать вновь добавленную строку в дополнение к исходному содержимому файла (конечно, учитывая, что я не нажимал ^ C).

Я отмечу это как домашнее задание, так как я хочу изучать и изучать Linux, но это не домашнее задание, это просто мое любопытство.


Ответы:


79

Вы можете использовать tail commandс -f :

tail -f /var/log/syslog 

Это хорошее решение для шоу в реальном времени.


Вы можете написать скрипт и перенаправить вывод в ваш скрипт.
Персидский залив

6
Вы также можете использовать -F(заглавная f), которая откроет файл, если он будет удален и заново создан по пути.
Петер

19

Если вы хотите показать короткий файл, который умещается на одном экране терминала, и то, что меняется, возможно, весь файл, вы можете использовать watch:

watch cat example.txt

Every 2.0s: cat example.txt                                Sun Aug  3 15:25:20 2014

Some text
another line

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

Опция -d( --differences) выделит изменения из предыдущей версии вывода или из первой версии.


9

Когда мне нужно обнаружить изменения файла и сделать что-то отличное от того tail -f filename, что делает, я использовал inotifywaitв скрипте, чтобы обнаружить изменение и действовать в соответствии с ним. Пример использования показан ниже. Смотрите man inotifywaitдля других имен событий и переключателей. Вам может понадобиться установить inotify-toolsпакет, например, через sudo apt-get install inotify-tools.

Вот пример сценария, который называется exec-on-change:

 #!/bin/sh

# Detect when file named by param $1 changes.
# When it changes, do command specified by other params.

F=$1
shift
P="$*"

# Result of inotifywait is put in S so it doesn't echo
while  S=$(inotifywait -eMODIFY $F 2>/dev/null)
do
  # Remove printf if timestamps not wanted 
  printf "At %s: \n" "$(date)"
  $P
done

В двух консолях я вводил команды следующим образом (где A> означает запись в консоли A, а B> означает запись в консоли B.)

A> rm t; touch t
B> ./exec-on-change t wc t
A> date >>t
A> date -R >>t
A> date -Ru >>t
A> cat t; rm t

В cat tконсоли A появился следующий вывод :

Thu Aug 16 11:57:01 MDT 2012
Thu, 16 Aug 2012 11:57:04 -0600
Thu, 16 Aug 2012 17:57:07 +0000

В exec-on-changeконсоли B появился следующий вывод :

At Thu Aug 16 11:57:01 MDT 2012: 
 1  6 29 t
At Thu Aug 16 11:57:04 MDT 2012: 
 2 12 61 t
At Thu Aug 16 11:57:07 MDT 2012: 
 3 18 93 t

exec-on-changeСценарий завершается , когда я rm«D t.


8

lessимеет режим следования, аналогичный tail -f- просто нажмите, Fкогда он у вас открыт.


4

У меня есть три решения:

1) tail -f хорошая идея

2) мы также tailfдолжны использовать

3) третий скрипт bash:

#!/bin/bash

GAP=10     #How long to wait
LOGFILE=$1 #File to log to

if [ "$#" -ne "1" ]; then
    echo "USAGE: `basename $0` <file with absolute path>"
    exit 1
fi


#Get current long of the file
len=`wc -l $LOGFILE | awk '{ print $1 }'`
echo "Current size is $len lines."

while :
do
    if [ -N $LOGFILE ]; then
        echo "`date`: New Entries in $LOGFILE: "
        newlen=`wc -l $LOGFILE | awk ' { print $1 }'`
        newlines=`expr $newlen - $len`
        tail -$newlines $LOGFILE
        len=$newlen
    fi
sleep $GAP
done
exit 0
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.