0

特定のステータスを確認し、結果を出力し、短時間スリープしてから、すべてを最初からやり直すためのスクリプトに取り組んでいます。出力は複数の行で構成されており、スクリプトで出力を更新して、同じ行に再度印刷するようにしたいと考えています。Mac と Linux で動作するはずです。これは私がこれまでに持っているものです:

#! /usr/bin/perl

use strict;

print `tput sc`; # Store cursor position

my @lines;

while (1) {
    @lines = ();

    push(@lines, `tput rc`); # Restore cursor position
    push(@lines, `tput ed`); # Clear from cursor to end of screen
    push(@lines, `dd if=/dev/urandom bs=1 count=1`); # This is just an example

    print @lines;

    sleep 1;
}

ターミナル ウィンドウの最後にカーソルを置いてスクリプトを呼び出さない限り、問題なく動作します。後者の場合、カーソルは印刷後にウィンドウの最後にとどまるため、元の位置に戻しても事実上何もせず、次の出力は新しい行に移動します。

どうすればそれを回避できますか?

tput clearorを呼び出したくありませんtput init。以前のコマンドと出力が失われる可能性があるためです。出力を開始する前にプロンプ​​トが一番上の行になるようにウィンドウをスクロールすることを考えていましたが、それには現在のカーソル行が必要であり、tput.

または、印刷された行数を覚えてから、 を使用してカーソルを戻すこともできますtput rin。ただし、出力が長すぎて 2 つ以上の端末行にまたがって中断された場合、これは機能しません。

4

1 に答える 1

3

一般に、この種のことを行うプログラムは、画面上の固定位置を使用するか、出力した行数を記憶して適切な量にジャンプします。

また、ほとんどの端末エミュレーション ウィンドウは、ウィンドウが空白になるまで下にスクロールするだけで、Clear Screen コマンドに応答することに注意してください。これは、以前に画面に表示されていた情報が引き続き「上」にあることを意味します。whileループを通過するたびに画面をクリアしないでください。クリア/ストアのコンボから始めることは、まさにあなたが必要としているものかもしれません.

カーソル制御のためにシェルアウトする代わりに、これらの余分なプロセスをすべて使用せずに、端末をより細かく制御しようとする場合がuse Cursesあります。use Term::ANSIScreen

追加のクレジット: カーソル制御文字列のシェルアウトを主張する場合tputは、ループの反復ごとにコマンドを生成しないでください。出力を記録し、パスごとに新しく印刷します。

印刷行を次のようなものに変更すると、バックティックからパイプオープンに変更した場合にジャンプバックする必要がある行数を正確に説明できるというprint @ANSI_control_strings, @lines;利点が追加される可能性があります。scalar @lines

于 2015-02-24T19:07:31.943 に答える