一時ファイル(いいえfifo / pipe)は複数のリーダースクリプトで監視する必要があります。各スクリプトは、次のコードを使用してバックグラウンドプロセスを使用して一時ファイルを監視します。
function file_relay {
# $1 is a regular file to read from
local bg_file
bg_file="$1"
# $2 is a fifo to relay to
local outfile
outfile="$2"
tail -f "$bg_file" | while read -r line
do
[[ ! -z "$line" ]] && { printf "%s" "$line" >>"$outfile"; }
done
}
起動時にファイル全体を読み取り、上記の関数が実行する新しい行を監視する必要があります。
file_relay /tmp/examplefile /tmp/examplefifo &
各スクリプトはまた、このファイルに行を出力します。したがって、これは複数の著者と複数の読者の状況です。
問題は、ファイルにリダイレクトを使用し、文字列の末尾に改行文字があっても完全な行がtail -f
使用できるまで待たないことがあることです。printf
これにより、読んでいる行が破損し、最後の行の最初の単語が前の行の最後に追加され、次のような結果が得られます。
This is one lineThis
変える
This is one line
This is another line
解決しようとしているprintf
バッファリングの問題tail -f
とファイルの周りに書き込みを使用すること(上記の関数ではファイルは読み取り専用なので、ファイル全体をsync
読み取ろうとする前にその行を強制的にtail
実行する方法がわかりませんsync
)。stdbuf
どこにも影響を与えないようで、-z
forまたは文字列をwithまたはotherとして使用または終了するtail
ことも同様です。$'\0'
すぐに発生するのを防ぐ唯一の方法は、ループが始まるsync
前ですwhile
が、ループが始まっても発生するのを防ぎません。
tail -f
強制的に行全体を読むようにする方法はありますか?
答え1
短い:直接ではありません
長い:移植性がない。POSIX)、しかしLinuxにのみ興味があるなら、パイプを通して出力tail -f
何かを通してはいラインバッファリング。たとえば、提案したようにUnixコマンド 'tail'に '--line-buffered'オプションはありません。、GNU grepには--line-buffered
次のことができるオプションがあります。
tail -f "$bg_file" | grep --line-buffered -E '^.*$'
しかし手動指摘
--line-buffered
ラインバッファリングを使用してください。これはパフォーマンスが低下する可能性があります。。
(FreeBSD同じオプションと説明があります。オープンBSD 2004、いいえPOSIXしかし…)。
文書にはこれについては記載されていませんが、2001年に初めて提出されました私はそれをするのに時間がかかりましたfflush
。