Зміст вихідного файлу під час їх зміни


47

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

magic_command foobar

Поточний термінал повинен відображати вміст файлу і чекати, поки я не знаю, натискаю ^ C.

Тоді якщо з іншого терміналу я роблю:

echo asdf >> foobar

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

Я позначаю це як домашнє завдання, оскільки хочу вивчити та вивчити linux, але це не домашнє завдання, це лише моя цікавість.


Відповіді:


79

Ви можете використовувати tail commandз -f :

tail -f /var/log/syslog 

Це гарне рішення для шоу в режимі реального часу.


Ви можете написати сценарій і перенаправити результат на свій сценарій.
PersianGulf

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) третій - це баш сценарій:

#!/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.