Nội dung tập tin đầu ra trong khi chúng thay đổi


47

Tôi muốn xuất nội dung của tệp trong khi chúng thay đổi, ví dụ: nếu tôi có tệp foobarvà tôi làm:

magic_command foobar

Thiết bị đầu cuối hiện tại sẽ hiển thị nội dung của tệp và đợi cho đến khi tôi không biết, tôi nhấn ^ C.

Sau đó, nếu từ một thiết bị đầu cuối khác, tôi làm:

echo asdf >> foobar

Thiết bị đầu cuối đầu tiên sẽ hiển thị dòng mới được thêm vào bên trong nội dung tệp gốc (tất nhiên, với điều kiện là tôi đã không nhấn ^ C).

Tôi sẽ đánh dấu đây là bài tập về nhà vì tôi muốn khám phá và học linux, nhưng nó không phải là bài tập về nhà, nó chỉ là một sự tò mò của tôi.


Câu trả lời:


79

Bạn có thể sử dụng tail commandvới -f :

tail -f /var/log/syslog 

Đó là giải pháp tốt cho chương trình thời gian thực.


bạn có thể viết một tập lệnh và chuyển hướng đầu ra của bạn đến tập lệnh của bạn.
Tiếng Ba Tư

6
Bạn cũng có thể sử dụng -F(viết hoa f), sẽ mở lại tệp nếu nó bị xóa và được tạo lại trên đường đi.
peterph

19

Nếu bạn muốn hiển thị một tệp ngắn, phù hợp trên một màn hình đầu cuối và những gì đang thay đổi có thể là toàn bộ tệp, bạn có thể sử dụng watch:

watch cat example.txt

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

Some text
another line

Nó hiển thị toàn bộ tệp cứ sau 2 giây, bao gồm một tiêu đề tùy chọn:

Tùy chọn -d( --differences) sẽ làm nổi bật các thay đổi từ phiên bản đầu ra trước đó hoặc từ phiên bản đầu tiên.


9

Khi tôi cần phát hiện các thay đổi của tệp và thực hiện một số thứ khác ngoài những gì tail -f filenamechúng tôi đã sử dụng inotifywaittrong một tập lệnh để phát hiện thay đổi và hành động theo nó. Một ví dụ về việc sử dụng được hiển thị dưới đây. Xem man inotifywaittên sự kiện và chuyển đổi khác. Bạn có thể cần phải cài đặt inotify-toolsgói, ví dụ thông qua sudo apt-get install inotify-tools.

Đây là kịch bản ví dụ, được gọi là 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

Trong hai bảng điều khiển, tôi đã nhập các lệnh như sau (trong đó A> có nghĩa là mục nhập trong bảng điều khiển A và B> có nghĩa là mục nhập trong bảng điều khiển 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

Đầu ra sau cat txuất hiện trong giao diện điều khiển 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

Đầu ra sau exec-on-changexuất hiện trong giao diện điều khiển 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

Các exec-on-changekịch bản chấm dứt khi tôi rm'd t.


8

lesscó chế độ theo dõi tương tự tail -f- chỉ cần nhấn Fkhi bạn mở.


4

Tôi có ba giải pháp:

1) tail -f là một ý tưởng tốt

2) chúng tôi cũng tailfphải sử dụng

3) cái thứ ba là một tập lệnh 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.