4 ms·
> it's not a seekable file. The flow I've described works on non-seekable files (and pipes). After you reach the end of file in one pass, you are allowed to tr
by acqq 7y ago
> it's not a seekable file.
The flow I've described works on non-seekable files (and pipes). After you reach the end of file in one pass, you are allowed to try to read again in the next, and the file pointer stayed on the same position if you haven't closed the file (and of course you should not close it). If the other process wrote something, the next time read will succeed. If you don't want to display the partial line before the line feed is written, you have to collect the read bytes before you read the line feed. It's all doable in Perl.
The only case I've seen something of what I've described not working was some case under some non-recent version of Wine, and I don't know if they fixed that. Otherwise Perl and POSIX support everything described.
- acqq 7y agoA small demo: gen_lines.pl: #!/usr/bin/env perl $| = 1; while (1) { print "line $n\n"; $n++; sleep( 3 ); } show_10.pl: #!/usr/bin/env perl $u = 1; @lines = (); while (1) { $line = <>; push @lines, $line; shift @lines if ( scalar( @lines ) > 10 ); print "10 lines update $u:\n"; $u++; for $l ( reverse @lines ) { print $l; } sleep( 1 ); } ./gen_lines.pl | ./show_10.pl
- Arnavion 7y agoOkay, I thought you were trying to say that perl could resume reading from the last position of the file after closing and reopening it, which would require a seekable file to work. If you were referring to leaving the file open across multiple iterations, then yes that is already what I said in the first post that you responded to. It's obvious that perl can do it; any program can.
- acqq 7y ago> It's obvious that perl can do it; any program can. I'm not aware how shell scripts or awk could do that. Maybe you can explain. I knew about Perl and that's what I showed.
- Arnavion 7y agoIn awk, `"foo" | getline` spawns `foo` and reads the first line from it, or reads the next line from the previous invocation of `foo` if that hasn't been closed yet. You have to explicitly call `close("foo")` to make the next invocation of `"foo" | getline` spawn a new `foo` instead of reading another line from the previous one. In shell, you'd just move the invocation of `foo` outside the dashboard loop, ie `foo | while :; do if read -r line; then ...; fi; sleep 1; done` The hard part is not to read from the same command across multiple dashboard iterations. The hard part is detecting that there is nothing more to read from the command without blocking, so that the dashboard can continue rendering if there's no more input. As I wrote in the first post that you responded to, gawk has `PROCINFO["read_timeout"]` to help with this (`getline` will return a specific error that the script can detect and break out of the loop), but FreeBSD's awk does not, which is why I was thinking of investigating whether Perl can do it.
- acqq 7y ago> The hard part is detecting that there is nothing more to read from the command without blocking In Perl $file->blocking( 0 ) or fcntl with O_NONBLOCK enables non-blocking sysread, I’ve recently used that. https://perldoc.perl.org/IO/Handle.html https://perldoc.perl.org/IO/Handle.html https://perldoc.perl.org/functions/fcntl.html https://perldoc.perl.org/functions/fcntl.html https://perldoc.perl.org/functions/sysread.html https://perldoc.perl.org/functions/sysread.html