unix / linuxでバッファリングせずに出力をファイルにリダイレクトする方法はありますか?


49

デバッグとプロセスの情報を標準出力に出力する、長時間実行されるバッチプロセスがあります。端末から実行するだけなら、「現在の場所」を追跡できますが、データが多すぎて画面からスクロールしてしまいます。

出力をファイル '> out.txt'にリダイレクトすると、最終的に出力全体が取得されますが、バッファリングされているため、現在何をしているかがわかりません。

出力をリダイレクトする方法はありますが、書き込みをバッファリングしないようにしますか?


1
以下の私の(および@cnstの) "議論"をご覧ください。ファイルにログを記録すると同時に出力を表示することが唯一の目的だと思います。解決策を見つけた場合は、それについてお知らせください;)!
ベンジ

回答:


52

setvbufCの呼び出しを使用して標準ストリームのバッファリングオプションを明示的に設定できます(このリンクを参照)が、既存のプログラムの動作を変更しようとする場合はstdbufcoreutilsバージョン7.5以降のように見える)を試してください。

これはstdout1行までバッファリングします。

stdbuf -oL command > output

これにより、stdoutバッファリングが完全に無効になります。

stdbuf -o0 command > output

aaarghhh ...私のUbuntuには7.4のcoreutilsしかありません... :(
Calmarius

@Calmarius:coreutilsのコンパイルは非常に簡単です。ftp.gnu.org/gnu/coreutilsから新しいバージョンを入手して、試してみてください。それは標準的な./configure && make運賃です。後でインストールする必要さえありません。stdbufバイナリoffを使用するだけsrc/です。
エドゥアルドイヴァネック

ダブル引数。古いCentOSディストリビューションとOSXおよびUbuntuでこれが必要です。
edk750 14


既知のPIDで既に実行中のプロセスに対して、パイプ/ printfバッファーを外部に強制する方法はありますか?
ムヴォリセク

9

script次のようなコマンドを使用して、ファイルへの行バッファー出力を実現できます。

stty -echo -onlcr   # avoid added \r in output
script -q /dev/null batch_process | tee output.log        # Mac OS X, FreeBSD
script -q -c "batch_process" /dev/null | tee output.log   # Linux
stty echo onlcr

-1理由:a)受け入れられた回答とは異なり、バックグラウンドでコマンドを実行する場合、これは機能しません(少なくとも私のLinuxボックスでは、上記のコマンドにbatch_process追加&すると、コマンドはすぐに終了します)。非常に一般的なユースケースのように、およびb)この呪文がどのように機能するかについての説明はここにはありません。
マークアメリー

8

Ubuntuでは、unbuffer(からのexpect-dev)プログラムパッケージが私にとってはうまくいきました。ただ走れ:

unbuffer your_command

バッファリングしません。


6

私が見つけた最も簡単な解決策(サードパーティのパッケージをインストールする必要はありませんでした)は、Unix&Linuxサイトの同様のスレッドで言及されています:scriptコマンドを使用します。それは古く、おそらく既にインストールされています。

$ script -q /dev/null long_running_command | print_progress       # FreeBSD, Mac OS X
$ script -q -c "long_running_command" /dev/null | print_progress  # Linux

コマンドの最初のファイル名パラメータscriptは、書き込まれるログファイルであることに注意しください。単に実行script -q your_commandすると、インデントしたコマンドを実行してログファイルで上書きします。man script試す前に、安全であることを確認してください。


4

scriptコマンドを試してください。システムがそれを持っている場合、引数としてファイル名を取り、stdoutにダンプされたすべてのテキストがファイルにコピーされます。セットアッププログラムで操作が必要な場合に非常に便利です。


「script -a out.txt」のトリックを知っています。書き込みプロセスをバッファリングしない他の方法があるかどうか疑問に思っていました。
ジェームスディーン

3

個人的には、調べたいコマンドの出力をパイピングすることを好みteeます。

scriptキーを押すタイミングなどの情報が多すぎて、印刷できない文字がたくさんあります。どのようなtee節約ははるかに人間が読める私のためです。


また、コマンドラインに「| less」を追加します。
ハブ

4
teeバッファリングの影響も受けていると確信しています。findコマンドからの出力を分割するときに、teeによってまだ部分的な行が表示されることがよくあります。
マゼラン

2

出力をファイルにリダイレクトし、ファイルの後にtail -fコマンドを続けます。

編集

それでもバッファリングの影響を受ける場合は、syslog機能(通常はバッファリングされていない)を使用します。バッチプロセスがシェルスクリプトとして実行される場合は、loggerコマンドを使用してこれを実行できます。バッチジョブがスクリプト言語で実行される場合、とにかくログ機能が必要です。


3
これは私が今やっていることですが、プロセスはファイルへの書き込みをバッファリングするので、それは私が避けたいものです。
ジェームス・ディーン

更新された提案の編集を参照してください。
wolfgangsz

1
これは明らかな理由で機能しません。役に立たThis answer is usefulず、おそらく役に立たない答えのために地獄は誰を配りますか?
cnst

1

tee魔法のコマンドを使用できます!

someCommand | tee logFile.log意志の両方のログファイルへのコンソールと書き込みの表示が。


動作しません。 teeバッファリングの実行を停止しません。
cnst

1
@cnst事実上、teeバッファリングは避けられませんが、出力が何であるかを見ることができるだけです。これは@JamesDeanが望んでいたことです(私は彼の質問を取り消すように)が、ここではバッファリングは本当に問題ではないと思います。詳細がありましたら、お知らせください。
Benj

彼は出力を見たいと思っていましたが、(バッファされていない方法で)出力teeを取得していませんが、取得していない出力をよりよく見るために使用することをお勧めしますか?
cnst

1
@JamesDeanの質問を赤にする方法:「出力をファイル '> out.txt'にリダイレクトする」ということは、コンソール出力がないことを意味し、出力全体がリダイレクトされるまでプロセスが完了するのを待ちます。使用中>は、コンソールに何も表示されません。@JamesDeanはそれを説明するために「バッファリング」という言葉を使用していると思います。彼が何を望んでいるのかについて、彼に質問するためのコメントを投稿します。
Benj
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.