2011-01-13 32 views
5

Tôi muốn kiểm tra tệp trong khoảng thời gian liên tục cho nội dung tiếp tục thay đổi. "tail -f" không đủ khi tệp không tăng kích thước.thay thế "đuôi -f" không cuộn cửa sổ đầu cuối

tôi có thể sử dụng một cách đơn giản trong khi vòng lặp trong bash để tác dụng tương tự:

while [ 1 ]; do cat /proc/acpi/battery/BAT1/state ; sleep 10; done 

Nó hoạt động, mặc dù nó có tác dụng không mong muốn của di chuyển cửa sổ terminal của tôi.

Vì vậy, bây giờ tôi tự hỏi, có một lệnh linux/shell sẽ hiển thị đầu ra của tệp này mà không cần cuộn thiết bị đầu cuối không?

+0

bạn đã thử xem chưa? – Rozuur

+0

Tôi chưa từng nhận được lời đề nghị đó trước đây. –

+0

Có rất nhiều câu trả lời đúng cho điều này. Nhờ gabuzo, SiegeX, Jander và Omnifarious. Nhưng người gần nhất với những gì tôi muốn đến từ Dennis Williamson. Cảm ơn tất cả mọi người đã dành thời gian! –

Trả lời

6

Kết hợp một số ý tưởng từ các câu trả lời khác cộng với một vài thủ thuật khác, thao tác này sẽ xuất tệp mà không xóa màn hình hoặc cuộn (ngoại trừ chu kỳ đầu tiên nếu lời nhắc ở cuối màn hình).

up=$(tput cuu1)$(tput el); while true; do (IFS=$'\n'; a=($(</proc/acpi/battery/BAT1/state)); echo "${a[*]}"; sleep 1; printf "%.0s$up" ${a[@]}); done 

Đó rõ ràng là một cái gì đó bạn sẽ không gõ bằng tay, vì vậy bạn có thể làm cho nó một chức năng mà mất tên tập tin, số giây giữa các cập nhật, bắt đầu dòng và số dòng như các đối số.

watchit() { 
    local up=$(tput cuu1)$(tput el) IFS=$'\n' lines 
    local start=${3:-0} end 
    while true 
    do 
     lines=($(<"$1")) 
     end=${4:-${#lines[@]}} 
     echo "${lines[*]:$start:$end}" 
     sleep ${2:-1} 
     # go up and clear each line 
     printf "%.0s$up" "${lines[@]:$start:$end}" 
    done 
} 

Run nó:

watchit /proc/acpi/battery/BAT1/state .5 0 6 

Đối số thứ hai (giây giữa cập nhật) mặc định là 1. (dòng bắt đầu) số thứ ba mặc định là 0.Đối số thứ tư (số dòng) mặc định cho toàn bộ tệp. Nếu bạn bỏ qua số lượng các dòng và tập tin phát triển nó có thể gây ra di chuyển để chứa các dòng mới.

Chỉnh sửa: Tôi đã thêm đối số để kiểm soát tần suất cập nhật.

+0

Ban đầu tôi đã đặt một biến thể với 'tput cup 0 0' nhưng tôi đã xóa nó vì nó yêu cầu' clear' và không có khả năng bắt đầu xuất hiện ở vị trí hiện tại của con trỏ. Kịch bản của bạn là chính xác những gì tôi mong muốn được. Tôi không biết về hai tham số 'tput' đó. Tôi sẽ phải tìm hiểu thêm về 'tput' cho các kịch bản trong tương lai. +1 – SiegeX

+0

P.S. Tôi nghĩ rằng bạn có thể chỉ đơn giản là kịch bản của bạn chỉ là một chút bằng cách sử dụng 'local lines = ($ (<" $ 1 ")) IFS = $ '\ n'' thay vì' read' với chuỗi ở đây – SiegeX

+0

@SiegeX: Cảm ơn. Tôi đã đi một đường vòng với 'đọc' cho một số lý do có ý nghĩa vào thời điểm đó, sau đó không quay lại khi nó không cần thiết. Tôi sẽ chỉnh sửa câu trả lời của mình. –

12
watch -n 10 cat /proc/acpi/battery/BAT1/state 

Bạn có thể thêm -d cờ nếu bạn muốn nó để làm nổi bật sự khác biệt từ một lần lặp tiếp theo.

+0

+1 cho cờ '-d' – gabuzo

+0

Lưu ý rằng' xem' được cài đặt mặc định trong Debian nhưng không được cài đặt BSD. –

+1

@jleedev: Lưu ý rằng BSD không phải là linux. – slebetman

9

watch là bạn của bạn. Nó sử dụng lời nguyền để nó sẽ không cuộn thiết bị đầu cuối của bạn.

Usage: watch [-dhntv] [--differences[=cumulative]] [--help] [--interval=<n>] [--no-title] [--version] <command> 
    -d, --differences[=cumulative]  highlight changes between updates 
       (cumulative means highlighting is cumulative) 
    -h, --help       print a summary of the options 
    -n, --interval=<seconds>    seconds to wait between updates 
    -v, --version       print the version number 
    -t, --no-title      turns off showing the header 

Vì vậy, dùng ví dụ của bạn nó sẽ được:

watch -n 10 cat /proc/acpi/battery/BAT1/state 
+0

Tôi đã không cung cấp cho bạn - 1, người khác đã làm cho về cơ bản đưa ra một câu trả lời trùng lặp. – Omnifarious

+0

Wow, điều đó thật khắc nghiệt, chúng tôi đã làm điều này cùng một lúc. – gabuzo

+1

+1 để truy cập ngu ngốc -1 – slebetman

3

ưa thích của tôi, mà làm việc ở những nơi mà không có watch, là thế này:

while true; do clear ; cat /proc/acpi/battery/BAT1/state ; sleep 10; done 
+0

Thú vị về điều này. Cảm ơn! –

3

Các kinh điển (và câu trả lời dễ nhất, linh hoạt nhất) là watch, như những người khác đã nói. Nhưng nếu bạn chỉ muốn xem dòng đầu tiên của một tệp, đây là giải pháp thay thế không xóa hoặc cuộn thiết bị đầu cuối:

while line=`head -n 1 /proc/acpi/battery/BAT1/state` \ 
    && printf "%s\r" "$line" \ 
    && sleep 10 
do 
    printf "%s\r" "`echo -n "$line" | sed 's/./ /g'`" 
done 
echo 

Phương tiện vận chuyển là khái niệm cốt lõi ở đây. Nó báo cho con trỏ trở về đầu dòng hiện tại, như một dòng mới nhưng không chuyển sang dòng tiếp theo. Lệnh printf được sử dụng ở đây vì (1) nó không tự động thêm một dòng mới, và (2) nó dịch \r thành một dấu xuống dòng.

Đầu tiên printf in dòng của bạn. Cái thứ hai xóa nó bằng cách ghi đè lên nó bằng dấu cách, để bạn không thấy rác nếu dòng kế tiếp được in ngắn hơn.

Lưu ý rằng nếu dòng được in dài hơn chiều rộng của thiết bị đầu cuối của bạn, thiết bị đầu cuối sẽ vẫn cuộn.

+0

Khá tuyệt! Bây giờ nếu điều này có thể làm việc cho 6 dòng thay vì một, nó sẽ là hoàn hảo. –

+2

Điều này có thể được thực hiện đơn giản hơn một chút với: 'while line = $ (head -n 1/proc/acpi/pin/BAT1/state); printf "% - * s \ r" $ COLUMNS "$ line"; ngủ 10; done' – SiegeX

+0

@SiegeX: Nice printf làm chủ! Tôi đã không nhận ra rằng bạn có thể làm điều đó với shell printf. Ngoài ra, tôi đã có thể mong đợi con trỏ để bọc sau khi in ký tự $ COLUMNS'th, nhưng thử nghiệm nói khác đi. – Jander

Các vấn đề liên quan