25

次のようなスクリプトがあります。

#!/bin/bash
exec /usr/bin/some_binary > /tmp/my.log 2>&1

問題は、some_binaryすべてのログを標準出力に送信することです。バッファリングにより、出力が数行のチャンクでしか表示されなくなります。何かが動かなくなって、最後の行が何を言っているかを確認する必要がある場合、これは面倒です。

some_binary に影響を与える exec を実行する前に stdout をバッファリングしないようにする方法はありますか?

(ラッパー スクリプトは、exec の前にいくつかの環境変数を設定するだけなので、perl または python での解決策も実現可能です。)

4

6 に答える 6

34

GNU coreutils-8.5 には、stdbufI/O ストリームのバッファリングを変更するコマンドもあります。

http://www.pixelbeat.org/programming/stdio_buffering/

したがって、あなたの例では、単に呼び出します:

stdbuf -oL /usr/bin/some_binary > /tmp/my.log 2>&1

これにより、テキストが行ごとにすぐに表示されます (行が C の行末"\n"文字で完了すると)。本当にすぐに出力したい場合は、-o0代わりに使用してください。

expectコマンドを介して依存関係を導入したくない場合は、この方法がより望ましい場合がありますunbufferunbuffer一方、some_binary実際の tty 標準出力に直面していると思い込ませる必要がある場合は、この方法が必要です。

于 2010-07-30T16:36:03.907 に答える
14

unbuffer付属のスクリプトexpectが役立つ場合があります。

于 2010-07-26T03:35:14.163 に答える
11

一部のコマンド ライン プログラムには、stdout ストリーム バッファリング動作を変更するオプションがあります。Cソースが利用可能であれば、それが進むべき道です...

# two command options ...
man file | less -p '--no-buffer'
man grep | less -p '--line-buffered'

# ... and their respective source code

# from: http://www.opensource.apple.com/source/file/file-6.2.1/file/src/file.c
if(nobuffer)
   (void) fflush(stdout);

# from: http://www.opensource.apple.com/source/grep/grep-28/grep/src/grep.c
if (line_buffered)
   fflush (stdout);

expect の unbuffer スクリプトを使用したり、プログラムのソース コードを変更したりする代わりに、 script(1) を使用して、パイプによって引き起こされる stdout の問題を回避することもできます。

参照: stdin がパイプではなく対話型であるとアプリケーションに思わせる

# Linux
script -c "[executable string]" /dev/null

# FreeBSD, Mac OS X
script -q /dev/null "[executable string]"
于 2010-07-26T16:57:06.897 に答える
3

私はインターネットで答えを探しましたが、uniq頑固すぎて次のものを除いてすべてをバッファリングできませんでしたstdbuf

{piped_command_here} | stdbuf -oL uniq | {more_piped_command_here}

于 2016-02-10T18:50:57.540 に答える
2

GNU Coreutils-8 には、本質的に LD_PRELOAD トリックを行う stdbuf と呼ばれるプログラムが含まれています。Linux で動作し、報告によると BSD システムでも動作します。

于 2013-12-23T10:57:28.833 に答える