2016-05-14 117 views
2

我正在使用Python的結構通過ssh在遠程主機上執行一些任務。
當顯示子任務的進度條時,其中一項任務在其輸出中使用回車符。類似這樣:處理Python結構中的回車( r)字符

int main(int argc, char* argv[]) { 

     int i; 

     for (i = 0; i <= 5; ++i) { 
       printf("\rProgress: %d%%", (int)(100 * ((float)i/5))); 
       fflush(stdout); 
       sleep(1); 
     } 
     printf("\n"); 

     return 0; 
} 

當這與Python的面料上運行:

def some_task(): 
    with settings(user = 'root'): 
     run('./task_with_progress_bar.out') 

tasks.execute(some_task, hosts = ['server_name']) 

面料會忽略和的\r,而不必在一條線路的進度條,我會得到的是:

[server_name] Executing task 'some_task' 
[server_name] run: ./task_with_progress_bar.out 
[server_name] out: 
[server_name] out: Progress: 0% 
[server_name] out: Progress: 20% 
[server_name] out: Progress: 40% 
[server_name] out: Progress: 60% 
[server_name] out: Progress: 80% 
[server_name] out: Progress: 100% 
[server_name] out: 

好像\r被視爲\n ...

上面的例子並不算太糟糕,但我正在運行的實際任務中充滿了進度條,這些進度條以較小的步進進行,並且這會污染整個控制檯併產生不必要的輸出。

有沒有辦法以某種方式定製輸出,以便Fabric不會忽略\r,但仍保持相同的一般格式:[<server_name>] <action_being_taken>?我喜歡這種格式,它整潔乾淨。

+0

間隔是否要抑制進度輸出,而不是其他的輸出? – malbarbo

+0

不,我不打壓輸出。我仍然希望它以[[server_name] ]的格式顯示,只是進度條不會以多行打印。我希望它被打印在顯示進度的一行中... –

回答

2

問題是織物正在轉變\r\n

一種解決這個問題是創建一個類似的類文件,並把它作爲stdout參數run,所以我們可以處理由調用程序產生的輸出和轉換\n\r。編寫這樣的課程的挑戰是確定哪些\n必須翻譯爲\r。這裏是嘗試,看起來爲"Progress:",以確定這樣的病例:

class FixProgress: 
    def __init__(self): 
     self.saw_progress = False 

    def write(self, s): 
     if 'Progress:' in s: 
      self.saw_progress = True 
     if s == '\n' and self.saw_progress: 
      sys.stdout.write('\r') 
      self.saw_progress = False 
     else: 
      sys.stdout.write(s) 

    def flush(self): 
     sys.stdout.flush() 

def some_task(): 
    with settings(user = 'root'): 
     run('./task_with_progress_bar.out', stdout = FixProgress()) 

這與問題的C程序工作正常。

+0

設置'pty = False'並沒有訣竅,並且由於輸出對於用戶來說是必要的,所以我無法抑制輸出(例如,當某些來自用戶的輸入是必需的)... –

+0

優雅的解決方案,正是我在找的,謝謝! –

+0

順便說一句,你怎麼知道'run()'是什麼參數? doc(http://docs.fabfile.org/en/1.11/api/core/operations.html?highlight=run#fabric.operations.run)只顯示'* args,** kwargs',但沒有指定... –

0

如果您可以更改輸出進度條的c文件的源代碼,則可以使用isatty()測試stdin是否爲tty。如果爲假,你可以在某些特定值抑制進度條輸出僅更新,即25。

http://linux.die.net/man/3/isatty

+0

我無法訪問源代碼... –