新しい行を書くのではなく、端末の行の内容を変更するにはどうすればよいですか?


24

そのためwget、Webページを取得すると、ファイルのダウンロード量を示すステータスバーが表示されます。次のようになります。

25%[=============>______________________________________] 25,000 100.0K/s (下線はスペースです。複数の連続したスペースをそこに入れる方法がわかりませんでした)

ただし、stdoutに別の行を書き込んで別の進行状況バーを追加する代わりに、次のように更新します。

50%[===========================>________________________] 50,000 100.0K/s

そしてwget、これも唯一の例ではありません。たとえば、何かをパイプしlessてから終了しても、以前に実行したコマンドの結果とともに、元のプロンプトがまだそこにあります。それはあなたが去ったことがないようなものです。

だから、私の質問は、これは何と呼ばれ、どのように実装するのですか、一度に1行だけで動作しますか、これをCで使用できますか?


5
BashFAQ 44を読むことをお勧めします。面白いかもしれません。
jw013

回答:


32

まず第一に、あなたの質問はbashとは関係なく、ターミナルと関係があります。端末はプログラムのテキストを表示するために応答しており、bash自体はプログラムが起動するとプログラムを制御できません。

端末には、色、フォント、カーソル位置などを制御する制御シーケンスが用意されています。標準化末端配列のリストは見てい http://www.termsys.demon.co.uk/vtansi.htm例えばあなたができるの

  • 行の先頭にカーソルを置きます
  • その後行を削除します
  • 新しい行を書く

進行状況バーを作成します。

より高度な端末エスケープシーケンスは通常、端末に依存します。たとえば、Etermまたはxtermでのみ動作します。ncurses-端末で対話型プログラムを作成するためのプログラミングライブラリであるため、エスケープシーケンスを使用する必要はありません。

既存の行を端末シーケンスで上書きする方法

echo long text
sleep 1
printf "\033[1A"  # move cursor one line up
printf "\033[K"   # delete till end of line
echo foo

端末シーケンスなしで既存の行を上書きする方法

1つの簡単な解決策は、末尾に改行を書くのではなく、基本的にカーソルを行の先頭にリセットするキャリッジリターンを書くことです。

echo -n first 
sleep 1 
echo -ne "\rsecond"
echo

\rまたはキャリッジリターンが行の先頭にカーソルを置き、あなたが行の内容を上書きすることができます。

lessまたはのようなバッファを切り替えるvi

の動作はless、より高度な端末機能である代替画面にも起因しています。

VT102モードでは、ウィンドウの表示領域と同じサイズの代替画面バッファーを有効または無効にするエスケープシーケンスがあります。有効にすると、現在の画面が保存され、代替画面に置き換えられます。ウィンドウの上部からスクロールされた行の保存は、通常の画面が復元されるまで無効になります。xtermのtermcap(5)エントリにより、ビジュアルエディタvi(1)は、編集のために代替画面に切り替え、終了時に画面を復元できます。ポップアップメニューエントリにより、カットアンドペースト用の通常画面と代替画面を簡単に切り替えることができます。

http://rosettacode.org/wiki/Terminal_control/Preserve_screenにtputまたはエスケープシーケンスを使用して自分で行う方法の例を示します。


15

echowhich を使用する代わりに、文字列に自動的に改行を追加します。printf "%s\r" whateverキャリッジリターンはカーソルを現在の行の先頭に送ります。例:

seq 1 15 | while read num; do printf "%2d\r" $num; sleep 1; done; echo ""

端末のカーソルに応じて、実行するのがより楽しい場合がありますprintf "\r%2d " $num
グレンジャックマン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.