私の意図は、再帰的なログwget
を 'status bar'のように1行に出力することです。だから私は(私のwget
呼び出しは少しより多くのオプションを持っているが、私は説明した問題のためにのみ不可欠なもの左)このパイプラインを組み立て:複雑なbashパイプラインがジャンプで動作する
wget -r -nv ftp://example.com 2>&1 | cut -c1-80 | xargs -I line echo -ne 'line\033[0K\r'
は私がやって何を意味するのか説明しましょう。多分私の命令には何か問題があります。
- は「再帰的ダウンロード」を意味します。
-nv
は、それぞれのダウンロードに関するメッセージを「time:URL - > local file」のように簡潔にします。- stderrをstdoutにリダイレクトするので、パイプでメッセージを処理できます。
| cut -c1-80
は、出力行を80文字にカットします。時には、URLとローカルファイル名が一緒になって長い文字列を作成し、行を2つ以上に分割します。そして私はそれをコンソールの1行に収める必要があります。 80は単なる例である。私のスクリプトでは、コンソールの幅をtput cols
と決めています。| xargs -I line echo -ne 'line\033[0K\r'
は、前のコマンドの出力を表示し、次の2つの特殊文字を追加します。\033[OK
- 行末。prevoiusの出力から残りの文字があれば残りの行を消去します。\r
- 現在の行の先頭にカーソルを設定するキャリッジリターン。
だから、希望の動作は次のとおりです。
wget
は、ファイルをダウンロードし、すぐにcut
stdoutにこのことについての通知を印刷しようとするwgetコマンドの出力をインターセプトし、80個の文字にそれをトリミングxargs
トリミングされた行をキャッチしてそれを印刷しますすぐにと特殊文字
現在のダウンロードが表示されるステータスバーが表示されます。
しかし!私が見ていることは10秒から60秒間は何も起こらず、その間に行われたダウンロードに関するすべてのメッセージは約1秒で印刷されます。彼らは実際に私が望むように、しかし非常に速く印刷しました。次に、ポーズ、1秒間のメッセージの別の部分、など。だから、すぐに -nessを除いてすべてが問題ありません。
xargs
部分を削除すると、メッセージはすぐに表示されます(ただし、1行では表示されません)。私がcut
呼び出しを取り除くと、それらは瞬間ですが、実際には長いURLで改行されることがあります。 echo
から特殊文字のみを取り除いても、出力は "跳ね上がり"、1行ではありません。
これを再現するには、「ftp://example.com」を再帰的なダウンロードのテストに使用できる任意のURL(HTTPも同様)に置き換えることができます。つまり、FTPに多数のファイルとディレクトリがあり、 HTTPの場合は、より多くのリンクを持つページへのリンクがたくさんあります(すべてのインターネットをダウンロードしようとする恐れはありません)。-r
オプションのデフォルトの再帰レベルは5です。これを再現できない場合は、配布に問題があると思われますので、下記のコメント欄に記入してください。
P.S. wget
のステータスバーを整理するためのより良い方法が分かっているなら、あなたのコメントは大歓迎です。しかし、私はBashを学んでいて、何がこのような奇妙な行動を引き起こしているのか知りたいと思っています。たぶん、パイプやecho
またはxargs
についてわかりません。ですから、このパイプラインは私が期待した通りに動作するのではないかという疑問があります。
ありがとう!今私は問題(バッファリング)とそれをバイパスする方法(awk)の原因を知っています。そして確かに、xargsは文字列の操作にはあまり適していません。 – Hnatt
その結果、私のパイプラインは次のようになりました: 'wget -r -nv http://example.com 2>&1 | awk -Wインタラクティブ '{ORS = ""; print substr($ 0,1,80) "\ 033 [0K \ r"} ''。 '-W interactive'はawksに出力をバッファしないようにし、' ORS = "" 'は改行なしで' print'を与えます。 – Hnatt