sharkdp / shell-functools

Functional programming tools for the shell
MIT License
1.19k stars 49 forks source link

filtering in a stream doesn't work as expected #41

Closed dickshaydle closed 3 years ago

dickshaydle commented 3 years ago

if i look in the stream of syslog for a word, the output is as expected

>tail -f /var/log/syslog | map contains Attached  
False
False
False
False
True
False

but if i filter for True nothing comes out

>tail -f /var/log/syslog | map contains Attached | filter equals True 

Strangely it works if the stream is saved to a file before

>tail -f /var/log/syslog > syslog.temp
>cat syslog.temp | map contains Attached | filter equals True
True
True

latest version: 0.3.0

dickshaydle commented 3 years ago

maybe it has something to do with the buffer. A similar similar command with grep shows the same problem

>tail -f /var/log/syslog | grep Attached | while read line ; do echo "$line"; done

but with the --line-buffered parameter it runs smoothly

>tail -f /var/log/syslog | grep --line-buffered Attached | while read line ; do echo "$line"; done
Nov 30 02:30:23 mycomputername kernel: [498264.335276] sd 8:0:0:0: [sdc] Attached SCSI removable disk
...

Commonly suggested solutions like stdbuf -i0 -o0 -e0 somecommand and unbuffer somecommand don't seem to have an effect.

dickshaydle commented 3 years ago

unbuffer -p has an effect:

tail -f /var/log/syslog | unbuffer -p map contains Attached | unbuffer -p map append " " | map replace True "aaaa"

is responding but with filter it is not:

tail -f /var/log/syslog | unbuffer -p map contains Attached | unbuffer -p map append " " | filter eq True
sharkdp commented 3 years ago

Thank you for reporting this. That seems to be a problem in filter, indeed.

Another way to reproduce this:

(echo "A"; sleep 1; echo "B"; sleep 1; echo "A") | map contains A | filter equals True

This outputs

True
True

as it should, but the output is not streaming. Both lines are only printed after 2 seconds

sharkdp commented 3 years ago

Small correction: the problem seems to be with buffered writing in the map command, not with reading in filter. Observe:

(echo "A"; sleep 1; echo "B"; sleep 1; echo "A") | map append C

# versus

(echo "A"; sleep 1; echo "B"; sleep 1; echo "A") | map append C | cat

The first one streams to the console, the second does not.

sharkdp commented 3 years ago

Should hopefully be fixed via c79d764

dickshaydle commented 3 years ago

great it runs now.

Maybe this is not the right place, but i want want to say that your coding work really is bewundernswert. I absolutely love all your projects i've seen. Great sense for style and simplicity.

sharkdp commented 3 years ago

Maybe this is not the right place, but i want want to say that your coding work really is bewundernswert. I absolutely love all your projects i've seen. Great sense for style and simplicity.

Thank you very much for the feedback!