2014-12-06 26 views
2

有像ddrescue這樣的Linux終端程序可以更新終端輸出,而不管當前行位置如何。如何更新終端中的值

意味着目前的終端輸出,也許已經命令一些線路的

您運行ddrescue並更新KB /秒,電流I/O位置,並在最新的版本也有一個經過時間更新自己。值已更新,但屏幕上已打印的內容仍保留在那裏。

所有這些值都沒有更新由新線和任何一種向上滾動的任何屏幕填充,作爲事實上的終端滾動酒吧......不收縮:-)

的問題是在Linux下的ANSI C特定的問題,因爲ddrescue是用C++編寫的,而我希望能夠以類似的方式輸出,但是用C語言編寫。

如果您有任何將使用gcc linux編譯的示例代碼,你(例如,將出現在當前行上的時鐘並且在該確切位置上自我更新)

+0

Forogt感謝您任何暗示和或骷髏 – Robert 2014-12-06 16:25:21

+0

你可能會覺得ncurses庫很有趣。 – 2014-12-06 16:26:36

+0

對不起dandan78,我覺得你的編輯沒有什麼幫助,需要Linux中的ANSI C規範,否則誰讀,他怎麼能理解我們正在談論的終端?誰知道C可能對閱讀這篇文章感興趣?此編輯可能會導致愚蠢的回覆。 – Robert 2014-12-06 16:28:16

回答

1

終端尋找轉義序列(某些字節模式),支持顏色,光標定位,粗體等等。程序鉤入那些更新屏幕而不滾動

它不是C特定的,它被內置到終端(窗口終端仿真器)中。任何發送輸出到終端的東西都可以做到。切出ncurses庫; ncuses基和ncurses的文檔

舉個例子,這裏有一個tcsh的shell命令,將設置你的窗口標題窗口:

echo -n "\e]0;WINDOW\a" 

其中\e是ESC字符(^ [0x1B)和\a是BEL(報警,^ G,0x07)

編輯:好吧,那在tcsh中工作,但不在sh或bash中。

0

這是一個快速入侵,顯示使用ANSI轉義產生wget類似行爲的進度條。可以進行額外的約束檢查調整,但這僅僅是一個簡單的例子。在終端寬度爲sz(目前限制爲70個字符)的情況下,重複調用progress會產生一個進度條,其中總計t中的當前值爲n。完成對progress_clear的呼叫後,將清除線上剩餘的任何字符。 (也可以只打印newline離開竣工米就行了)

雖然逃逸代碼的可用性是終端相關的,在選擇時,\033[s保存光標位置)和\033[u恢復保存位置 )在支持逃生的終端之間相當普遍。

有許多方法來處理從printffieldwidthspadding格式來memcpy填補字符數組。這只是示出了具有逸出的線路控制輸出,以提供測量儀的主體:

#include <stdio.h> 
#include <unistd.h>  /* for usleep */ 

#define MAXPM 120 

/* progress meter called with current increment 'n' of a 
total number of increments 't' fit into a maximum terminal 
width of 'sz'. (< MAXPM) It should be called and updated 
without intervening output to stdout. 
*/ 
static inline void progress (int n, int t, int sz) 
{ 
    int pct = (n * 100)/t; 
    char mkr[] = { [0 ... MAXPM] = '=', [MAXPM+1] = 0 }; 
    char spc[] = { [0 ... MAXPM] = ' ', [MAXPM+1] = 0 }; 
    int nmkr = (pct * sz)/100; 
    int nspc = sz - nmkr; 

    mkr[nmkr] = 0;  /* terminate at appropriate size */ 
    spc[nspc] = 0; 

    printf ("\033[s\033[u %3d %% [%s%s]\033[u", pct, mkr, spc); 
    fflush (stdout); /* required due to no newline */ 
} 

/* simple clear to end of line - if desired, otherwise, just print newline */ 
void progress_clear() 
{ printf ("\033[K"); fflush (stdout); } 

int main() { 

    int i = 0; 

    for (i = 0; i <= 50; i++) { 
     /* do something that returns progress */ 
     progress (i, 50, 70); 
     usleep (100000); 
    } 
    // progress_clear(); /* clean up - remove meter (if wanted) */ 
    printf ("\n"); 

    return 0; 
} 

實施例(具有newline增補):

$ ./bin/progbar 
    0 % [                  ] 
    2 % [=                  ] 
    4 % [==                 ] 
    6 % [====                 ] 
(snip) 
    94 % [=================================================================  ] 
    96 % [=================================================================== ] 
    98 % [==================================================================== ] 
100 % [======================================================================]