クリア時にテキスト/画面の点滅を防止


11

私のスクリプトは次のようなことをしています:

while :;
   clear

   do_a_lot_of_output_here

   sleep 1
done

クリアして出力しているときに画面が点滅しないようにするオプションはありますか?watchコマンドのようにしたいのですが(それはで書かれていますC)。何かアドバイスは?

clear | hexdump -C

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

PS。使用しているbashだけです。


あなたの出力を追加できますclear | hexdump -Cか?
ott-- 2013年

質問を広げました。
ravnur 2013年

stackoverflow.com/questions/5367068/…で別の解決策を見つけました- echo -en "\ec"フラッシュもしますか?
ott-- 2013年

私もこれを見つけました。アンサーフラッシュの両方のバリアントも。
ravnur 2013年

:私は、このツールを使用して成功を収めていたexcess.org/article/2009/07/watch1-bash-unicode
レイン

回答:


8

スクリプトが画面全体をクリアするため、点滅が発生します。既存のテキストを上書きし、必要な場合にのみクリアすると、ちらつきは発生しません。

次に例を示します。

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

これを行います:

  • 画面に収まる特定のコマンドからの出力を印刷します(折り返しもスクロールもありません)。
  • 既存の行を上書きし、上書きされない各行の部分をクリアします
  • ed端末の機能を使用して、現在の場所から画面の最後まで印刷します。

サイズ変更可能な画面を処理したい場合は、割り当てを外側のループの内部ROWSCOLS内部に移動できます。たとえば、

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

ためには、tputシステムから現在のスクリーンサイズを要求します。

参考文献:


1
いくつかの機能を備えた小さなスタンドアロンスクリプトに組み込まれて使用#!/bin/bashしたい場合は、を使用watchitできますexport -f function_name; watchit function_name
aggregate116​​6877

これは、画面上部でおかしな問題に遭遇したことを除いて、完全に機能しましたhead。行数を計算するときの問題は、(少なくとも私の設定では-分割ペインのsshセッション、iTerm2の)1つずれたエラーのようです。ROWS=`expr $(tput lines) - 1`これに完全に対処しました。
ohruunuruus 16

これはすばらしいことです。@ thomas-dickeyに感謝します。
mbarkhau 2018

9

点滅を防止する1つの方法は、画面をクリアする前にすべての出力を取得して、画面をクリアしてから再描画するまでの時間を最小限にすることです。これはダブルバッファリングの概念に似ています。

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

これはちらつきを完全になくすわけではありませんが、私の経験ではそれほど頻繁には起こりません。


ダブルバッファリングは、他の状況と同様に、その日を
安全にし

魅力のように働いた。ちらつきはまったくありません:)
Lars Juel Jensen

1
残りのちらつきはclear、バッファにを含めることで解消できますoutput=$(clear; do_a_lot_of_output_here)
kdb 2017

@kdbいい提案です!これにより、ちらつきがほぼ完全になくなり、受け入れられた回答よりもはるかに簡単になります。
Michael Mior

これは魅力のように機能します!最初に、「echo "$ output"」の二重引用符を省略しました。その後、すべての行が混乱しています。(すべての空白は単一のスペースと見なされます。)
ポップアップ

5

点滅は、ループのたびに画面をクリアすることで避けられない結果です。カーソルを画面の上部に移動して、代わりに古い出力の一部を上書きすることができます。

# 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

このスクリプトは、出力が縮小するとアーティファクトを残します。また、携帯可能性も低いです。私はurxvt、xterm、およびstでのみテストしました。


この場合、カーソルはランダムな位置(もちろんアーティファクト)から出力の最後にジャンプし始めます。またtput clear、同じ結果(点滅)で試しました
ravnur 2013年

カーソルを隠すためにスクリプトに数行追加しました。

カーソルなし-ジャンプなし。しかし、アーティファクトについては?出力にはランダムな数の行があります。新しい出力を開始する前に、すべてのスクリプトをスペースで埋める必要がありますか?しかし、とにかく、あなたの時間と努力に感謝します:そのため私から+1してください、しかしそれは私の問題を解決しません
ravnur

すべてのアーティファクトを取り除く唯一の方法を見つけました:tput ed。しかし、瞬きの原因になります
ravnur 2013年

どのターミナルエミュレータを使用していますか?tput ed直前do_a_lot...のライン、私はurxvtではなく、xtermやSTに点滅見ています。

1

Cristianの回答の拡張として、コンソールウィンドウがコマンドの出力よりも小さい場合に機能する次のbash関数を作成しました。

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

これにより、ウォッチャーに任意のコマンドを渡すことができます。gitを使用している場合は、を使用git config --global color.status alwaysしてから:

watcher git status

常に更新されるgitステータス出力を表示します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.