Ngăn chặn văn bản / màn hình nhấp nháy khi làm rõ


11

Kịch bản của tôi làm một cái gì đó như:

while :;
   clear

   do_a_lot_of_output_here

   sleep 1
done

Có bất kỳ tùy chọn nào để ngăn màn hình nhấp nháy khi tôi làm rõ và xuất không? Tôi muốn làm điều đó giống như trong watchlệnh (nhưng nó được viết bằng C). Có lời khuyên nào không?

clear | hexdump -C

00000000  1b 5b 48 1b 5b 32 4a                              |.[H.[2J|
00000007

Tái bút Tôi bashchỉ sử dụng .


Bạn có thể thêm đầu ra của bạn clear | hexdump -C?
ott--

Tôi đã mở rộng câu hỏi.
ravnur

Tôi đã tìm thấy một giải pháp khác trên stackoverflow.com/questions/5367068/ - - cũng có echo -en "\ec"flash không?
ott--

Tôi cũng tìm thấy cái này Cả hai biến thể từ câu trả lời flash quá.
ravnur

Tôi đã thành công với công cụ này: overs.org/article/2009/07/watch1-bash-unicode
raine

Câu trả lời:


8

Việc nhấp nháy xảy ra vì tập lệnh xóa toàn bộ màn hình. Nếu nó vẽ lên văn bản hiện có và chỉ xóa khi cần thiết, thì sẽ không có nhấp nháy.

Đây là một ví dụ:

#!/bin/sh
watchit() {
    HOME=$(tput cup 0 0)
    ED=$(tput ed)
    EL=$(tput el)
    ROWS=$(tput lines)
    COLS=$(tput cols)
    printf '%s%s' "$HOME" "$ED"
    while true
    do
        CMD="$@"
        ${SHELL:=sh} -c "$CMD" | head -n $ROWS | while IFS= read LINE; do
            printf '%-*.*s%s\n' $COLS $COLS "$LINE" "$EL"
        done
        printf '%s%s' "$ED" "$HOME"
        sleep 1
    done
}

watchit top -b -n 1

Nó làm điều này:

  • in đầu ra từ lệnh đã cho sẽ vừa trên màn hình (không bao bọc hoặc cuộn)
  • ghi trên các dòng hiện có, xóa phần của mỗi dòng không bị ghi đè
  • sử dụng edkhả năng của thiết bị đầu cuối của bạn để in từ vị trí hiện tại đến cuối màn hình.

Nếu bạn muốn xử lý một màn hình có thể thay đổi kích thước, bạn có thể di chuyển các bài tập đến ROWSCOLSbên trong vòng lặp bên ngoài, ví dụ:

#!/bin/sh
watchit() {
    HOME=$(tput cup 0 0)
    ED=$(tput ed)
    EL=$(tput el)
    printf '%s%s' "$HOME" "$ED"
    while true
    do
        ROWS=$(tput lines)
        COLS=$(tput cols)
        CMD="$@"
        ${SHELL:=sh} -c "$CMD" | head -n $ROWS | while IFS= read LINE; do
            printf '%-*.*s%s\n' $COLS $COLS "$LINE" "$EL"
        done
        printf '%s%s' "$ED" "$HOME"
        sleep 1
    done
}

watchit top -b -n 1

bởi vì tputyêu cầu sàng lọc hiện tại từ hệ thống.

Đọc thêm:


1
Đối với những người sử dụng #!/bin/bashvà muốn sử dụng watchitđược nhúng trong một tập lệnh độc lập nhỏ với một số chức năng, bạn có thể làm export -f function_name; watchit function_name.
tổng

Điều này hoạt động hoàn hảo đối với tôi ngoại trừ việc tôi gặp phải các vấn đề hài hước ở phía trên màn hình, nơi mọi thứ sẽ thay đổi và trở nên rối rắm cho các đoạn văn bản dài hơn (bất cứ điều gì được rút ngắn lại head). Có vẻ như sự cố là do lỗi một (ít nhất là trong thiết lập của tôi - phiên ssh trong các bảng phân tách, iTerm2) khi tính toán số lượng hàng. ROWS=`expr $(tput lines) - 1`giải quyết điều này một cách hoàn hảo.
ohruunuruus

Điều này thật tuyệt vời, cảm ơn bạn rất nhiều @ thomas-dickey.
mbarkhau

9

Một cách để giúp ngăn chặn flash là lấy tất cả đầu ra trước khi xóa màn hình để có một khoảng thời gian tối thiểu giữa việc xóa và vẽ lại nó. Điều này tương tự với khái niệm đệm đôi:

while :; do
   output=$(do_a_lot_of_output_here)
   clear
   echo "$output"
   sleep 1
done

Điều này không hoàn toàn loại bỏ nhấp nháy, nhưng nó xảy ra ít thường xuyên hơn theo kinh nghiệm của tôi.


Bộ đệm đôi, giống như trong mọi tình huống khác, két trong ngày :-)
Ikke

Làm việc như người ở. Không nhấp nháy chút nào :)
Lars Juel Jensen

1
Sự nhấp nháy còn lại có thể được loại bỏ bằng cách clearđưa vào bộ đệm, tức là output=$(clear; do_a_lot_of_output_here).
kdb

@kdb Gợi ý hay! Điều này gần như loại bỏ hoàn toàn nhấp nháy cho tôi và đơn giản hơn nhiều so với câu trả lời được chấp nhận.
Michael Mior

Công việc này như một cái duyên vậy! Lúc đầu, tôi đã bỏ lỡ các dấu ngoặc kép trong 'echo "$ output"', và sau đó các dòng bị rối tung lên. (Tất cả các khoảng trắng được coi là khoảng trắng đơn.)
Popup

5

Đèn flash là kết quả không thể tránh khỏi khi xóa màn hình mỗi lần xung quanh vòng lặp. Thay vào đó, bạn có thể di chuyển con trỏ lên phía trên màn hình và ghi đè lên các phần của đầu ra cũ.

# You may want to do this if your code is in a script.
unhide_cursor() {
    printf '\e[?25h'
}
trap unhide_cursor EXIT

# Hide the cursor (there is probably a much better way to do this)
printf '\e[?25l'
clear 
while true ; do
    # Move the cursor to the top of the screen but don't clear the screen
    printf '\033[;H' 
    do_a_lot_of_output_here
    sleep 1
done

Kịch bản này sẽ để lại các tạo phẩm nếu đầu ra của bạn co lại. Nó cũng không có khả năng là di động. Tôi chỉ thử nghiệm nó với urxvt, xterm và st.


Trong trường hợp này, con trỏ bắt đầu nhảy đến cuối đầu ra từ vị trí ngẫu nhiên (và tất nhiên là tạo tác). Ngoài ra tôi đã thử tput clearvới kết quả tương tự (nhấp nháy)
ravnur

Tôi đã thêm một vài dòng vào tập lệnh để ẩn con trỏ.

Không có con trỏ - không nhảy. Nhưng về hiện vật? Đầu ra có một lượng hàng ngẫu nhiên. Tôi có cần điền vào tất cả các tập lệnh với khoảng trắng trước khi bắt đầu đầu ra mới không? Nhưng, dù sao đi nữa, cảm ơn vì thời gian và nỗ lực của bạn: +1 từ tôi vì điều đó nhưng nó không giải quyết được vấn đề của tôi
ravnur

Tôi chỉ tìm thấy một cách để thoát khỏi tất cả các hiện vật : tput ed. Nhưng nó gây ra chớp mắt
ravnur

Trình giả lập thiết bị đầu cuối nào bạn đang sử dụng? Ở tput edngay trước do_a_lot...vạch, tôi thấy nhấp nháy trong urxvt nhưng không phải là xterm hay st.

1

Là một phần mở rộng của câu trả lời của Cristian, tôi đã thực hiện chức năng bash sau hoạt động nếu cửa sổ giao diện điều khiển nhỏ hơn đầu ra của lệnh:

function watcher()
{
    lines=$(tput lines)
    while true; do
        output="$($@ | head -n $lines)"
        clear
        echo -e "$output"
        sleep 2
    done
}

Điều này cho phép bạn chuyển bất kỳ lệnh nào cho người theo dõi. Nếu bạn đang sử dụng git, hãy sử dụng git config --global color.status alwaysvà sau đó:

watcher git status

Sẽ hiển thị một đầu ra trạng thái git luôn cập nhật.

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.