私のデスクトップにログファイルのメッセージをリアルタイムで表示したいです。 (Fedora 24のxfce4)
私の考えは、シェルスクリプトで通知を送信してtail -fを使用してこれを行うことです。
これまでに2つのシェルスクリプトがあります。
read_data.sh
write_data.sh
どちらもプロセスを分岐し、パイプを介して通信します。
write_data.sh
:
tail -f /var/log/logfile > mypipe
read_data.sh
:
mkfifo mypipe
while true
do
echo "read now from pipe"
if read line <mypipe; then
echo $line
fi
done
残念ながら、次のエラーメッセージが表示されます。
EPIPE (Broken pipe)
私は何が起こったかを分析するためにstraceを使用しました。
write_data.sh
:
strace tail -f /var/log/logfile > mypipe
....
write(1, "Message from logfile"..., 281) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=7314, si_uid=0} ---
+++ killed by SIGPIPE +++
strace read_data.sh
...
read(0, "\n", 1) = 1
dup2(10, 0) = 0
fcntl(10, F_GETFD) = 0x1 (flags FD_CLOEXEC)
close(10) = 0
open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFDIR|0550, st_size=4096, ...}) = 0
getdents(3, /* 133 entries */, 32768) = 5400
getdents(3, /* 0 entries */, 32768) = 0
close(3) = 0
write(1, "message from logfile ....
) = 62
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
write(1, "read now from pipe\n", 19read now from pipe
) = 19
open("/tmp/mypipe", O_RDONLY
read_data.sh
この時はブロックされます。
なぜこれが起こるのかご存知ですか?
答え1
SIGPIPE は、読み取りループが各反復で読み取るために FIFO ファイルを開閉することによって発生します。この試み:
while read line; do
echo "$line"
done <"$pipe"