次のコードを考えてみましょう(PHPで書かれていますが、それは問題ではありません。答えはおそらく純粋なBashです)。目標は、ターミナルラインの全幅を文字で埋めることです。
今最小化する端末幅の実行中に混乱を避けるために、最後の実行で超過した文字を消去する必要があります。
ただし、以前にエコーされた行は複数行に分割され、エコーはカーソルを\r
次に返します。最後代わりに、この行は最初、ゴミを残しています。
簡単な治療法はありませんか?私が考えることができる唯一のことは、接続が切断されたときに「CURSOR UP」を数回エコーするANSIコード(マイナス1)です。
#!/usr/bin/env php
<?php
// Make sure window is 80 characters wide when running script
echo "00000000001111111111222222222233333333334444444444555555555566666666667777777777";
sleep(3); // Narrow window here (to 40-50 characters or so)
echo "\033[2K"; // CLEAR LINE
echo "\033[A"; // CURSOR UP
echo "\033[2K"; // CLEAR LINE
echo "\r"; // GOTO BEGINNING OF LINE
echo "Now we're back were we begun (where 000... used to be)";
?>
ベストアンサー1
ターミナルエミュレータの「伝統的な」動作は、ウィンドウが狭くなると長い行を切り取ることであり、一部のターミナルでは、サイズが変更されたときに内容を再ラップすることです。あなたの質問は後者にのみ関連しています。
「ディスプレイの消去」エスケープシーケンス(コマンド:tput ed
、シーケンス\e[J
:)は、カーソル(含む)からディスプレイの終わりまですべての内容を消去します。これはおそらく最も簡単なオプションです。
ただし、行の最後の列に印刷した後でも、カーソルはまだ論理的に最後の列にあるため(一部のエミュレータがカーソルを非表示にしたり他の場所に表示したりしても)、この場合、このエスケープシーケンスは文字を消去します。メッセージの最後の文字が消去されないようにするには、新しいメッセージを印刷する前にカーソルが最初の列にある間にメッセージをエクスポートする必要があります。