更改时输出文件内容


47

我想在文件更改时输出文件的内容,例如,如果我有文件foobar并且这样做:

magic_command foobar

当前终端应显示文件的内容,并等待直到我不知道按^ C。

然后,如果从另一个终端执行:

echo asdf >> foobar

除原始文件内容外,第一个终端还应显示新添加的行(当然,考虑到我没有按^ C键)。

因为我想探索和学习linux,所以我将其标记为家庭作业,但这不是家庭作业,只是我的好奇心。


Answers:


79

你可以用tail command-f

tail -f /var/log/syslog 

这是实时显示的好解决方案。


您可以编写脚本并将输出重定向到脚本。
PersianGulf 2012年

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倒是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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.