This is the script for Reader, which should be close to what you need to fake a tail command for a NUL-filled file. It checks for changes in the file (by comparing the whole ls -l output, which includes a timestamp down to nanoseconds), and reports any additions in a batch. It does not report lines that are already in the file when it starts up, only additions while it is running.
It runs at two speeds to avoid wasted checks. If it detects any additions, it tries again after 1.0 seconds. If a cycle sees no additions, it tries again after 5 seconds (this 5 is an argument to the process).
#! /bin/bash
#: Reader: tail -f a file which is pre-formatted with many trailing NUL characters.
#### Implement the User Requirement.
function Reader {
local RUN="${1:-60}" SLEEP="${2:-5}" FILE="${3:-/dev/null}"
local AWK='''
BEGIN { NUL = "\000"; }
function Tick (Local, cmd, ts) {
cmd = "date \047+%s\047";
cmd | getline ts; close (cmd); return (ts);
}
function TS (Local, cmd, ts) {
cmd = "date \047+%H:%M:%S.%N\047";
cmd | getline ts; close (cmd); return (ts);
}
function Wait (secs) {
system (sprintf ("sleep %s", secs));
}
function isChange (Local, cmd, tx) {
cmd = sprintf ("ls 2>&1 -l --full-time \047%s\047", Fn);
cmd | getline tx; close (cmd);
if (tsFile == tx) return (0);
tsFile = tx;
if (index (tx, "\047")) {
if (fSt != "B") { fSt = "B"; printf ("%s: No file: %s\n", TS( ), Fn); }
} else {
if (fSt != "G") { fSt = "G"; printf ("%s: Reading: %s\n", TS( ), Fn); }
}
return (1);
}
function atNul (buf, Local, j) {
j = index (buf, NUL);
return ((j > 0) ? j : 1 + length (buf));
}
function List (tx, Local, ts, X, j) {
sub ("\012$", "", tx); split (tx, X, "\012");
ts = TS( );
for (j = 1; j in X; ++j) {
printf ("%s %3d :%s:\n", ts, length (X[j]), X[j]);
}
}
function Monitor (Local, rs, tk, Buf, Now, End) {
printf ("%s: READER Begins\n", TS( ));
tk = Tick( ); Expired = tk + Run;
Now = -1;
while (Tick( ) <= Expired) {
if (! isChange( )) { Wait( Sleep); continue; }
rs = RS; RS = "\000";
Buf = ""; getline Buf < Fn; close (Fn);
RS = rs;
if (Now < 0) Now = atNul( Buf);
End = atNul( Buf);
List( substr (Buf, Now, End - Now));
Now = End;
Wait( 1.0);
}
printf ("%s: READER Exits\n", TS( ));
}
NR == 1 { Run = $0; next; }
NR == 2 { Sleep = $0; next; }
NR == 3 { Fn = $0; }
END { Monitor( Fn); }
'''
{
echo "${RUN}";
echo "${SLEEP}";
echo "${FILE}";
} | awk -f <( echo "${AWK}" )
}
#### Script Body Starts Here.
Reader 40 5 "./myNullFile"
cat
displays only text, not zeros, thank you!inotifywait
frominotify-tools
may be a solution for this problem... I've tested the commandinotifywait --format=%w -q -m -e modify /home/myuser/file.txt
while writing nullbytes to the file withdd if=/dev/zero bs=1 count=1 >> /home/myuser/file.txt
and it detected when the file was modified (not what was modified or appended)