我的意圖是在一行中輸出遞歸日誌wget
,'status bar'-like。所以我組裝這條管道(我wget
調用有更多的選擇,但我離開所述問題的唯一本質):複雜的bash管道跳轉工作
wget -r -nv ftp://example.com 2>&1 | cut -c1-80 | xargs -I line echo -ne 'line\033[0K\r'
讓我解釋一下我的意思做。也許我的命令有問題。
-r
表示'遞歸下載';-nv
使有關每個下載的消息變得簡短,如:「time:URL - > local file」;- stderr重定向到標準輸出,所以我可以通過管道使用消息;
| cut -c1-80
將輸出行剪切爲80個字符。有時URL和本地文件名一起構成一個長的字符串,將一行分成兩行或更多。我需要它來適應單一行的控制檯。例如,80站在這裏。在我的腳本中,我用tput cols
確定控制檯寬度;輸出前一命令的| xargs -I line echo -ne 'line\033[0K\r'
印刷品和增加了兩個特殊字符:\033[OK
- 線的端部,如果有從prevoius輸出留下的任何字符,清潔線的其餘部分;和\r
- 回車,將光標設置爲當前行的開頭。
所以想要的行爲是:
wget
下載文件,並試圖打印這個通知,標準輸出cut
立即截獲的wget的輸出,並修剪到80個字符xargs
捕捉修剪線並將其打印立即帶特殊字符
所以我應該看到某種狀態欄,其中顯示當前下載。
但是!我看到的所有內容都沒有發生10到60秒,然後在大約1秒內打印出有關在此期間完成的所有有關下載的消息。他們實際上以我想要的方式打印,但速度非常快。然後再次暫停,另一部分消息在1秒鐘內,等等。所以一切都很好,除了立即-性。
當我刪除xargs
部分,消息被立即顯示(但不是在一行中)。當我刪除cut
電話時,它們是即時的,但有時候這條線路會打破一些非常長的URL。如果我只從echo
中刪除特殊字符,輸出仍然是「跳躍」而不是在一行中。
爲了重現這一點,你可以用任何可以用於測試遞歸下載的URL(HTTP也可以)替換「ftp://example.com」,也就是說,在FTP有很多文件和目錄的情況下HTTP的情況下有很多鏈接到有更多鏈接的頁面(不要害怕它可能會嘗試下載所有Internet,因爲-r
選項的默認遞歸級別爲5)。如果你不能重現這一點,那麼我認爲這是我的發行版有問題,請在下面的評論部分寫下它。
P.S.如果您知道更好的組織wget
的狀態欄的方式,您的意見非常受歡迎。但我正在學習Bash,並想知道是什麼導致了這種奇怪的行爲。也許有一些關於管道或echo
或xargs
我不知道。所以問題是爲什麼這個管道工作得如此而且沒有我預期的那樣。
謝謝!現在我知道是什麼導致了問題(緩衝)以及如何繞過它(awk)。是的,xargs真的不適合字符串操作。 – Hnatt 2012-03-09 13:36:43
因此,我現在的流水線如下所示:'wget -r -nv http://example.com 2>&1 | awk -W interactive'{ORS =「」;打印substr($ 0,1,80)「\ 033 [0K \ r」}「'。 '-W interactive'使得awks不會緩衝輸出,'ORS =「''給我們'print'沒有換行符。 – Hnatt 2012-03-09 13:56:50