bat icon indicating copy to clipboard operation
bat copied to clipboard

`bat /dev/zero | head -c 10` hangs while `cat` is not

Open xnuk opened this issue 2 years ago • 3 comments

What steps will reproduce the bug?

$ bat /dev/zero | head -c 10  # hangs forever
^C

$ cat /dev/zero | head -c 10  # while this does not

$ cat /dev/zero | head -c 10 | hexdump  # FYI
0000000 0000 0000 0000 0000 0000
000000a

$ bash -c 'bat /dev/zero | head -c 10'  # hangs, doesn't matter what shell I used
^C
$ dash -c 'bat /dev/zero | head -c 10'
^C
$ fish -c 'bat /dev/zero | head -c 10'
^C

What happens?

hangs

What did you expect to happen instead?

does not hang, and print ten NUL characters

How did you install bat?

pacman -S bat


bat version and environment

  • bat 0.23.0 (871abd27)
  • Arch Linux x64 (linux kernel: 6.4.11-zen2-1-zen)
  • fish, version 3.6.1
  • alacritty 0.12.2 (9d9982df)
  • less 643
Result of bat --diagnostic

Software version

bat 0.23.0 (871abd27)

Operating system

Linux 6.4.11-zen2-1-zen

Command-line

bat --diagnostic 

Environment variables

SHELL=/usr/bin/fish
PAGER=<not set>
LESS='-SFR --mouse'
LANG=ko_KR.UTF-8
LC_ALL=ko_KR.UTF-8
BAT_PAGER='less -SFR --mouse'
BAT_CACHE_PATH=<not set>
BAT_CONFIG_PATH=<not set>
BAT_OPTS=<not set>
BAT_STYLE=<not set>
BAT_TABS=<not set>
BAT_THEME=<not set>
XDG_CONFIG_HOME=/home/xnuk/.config
XDG_CACHE_HOME=<not set>
COLORTERM=truecolor
NO_COLOR=<not set>
MANPAGER=<not set>

System Config file

Could not read contents of '/etc/bat/config': No such file or directory (os error 2).

Config file

Could not read contents of '/home/xnuk/.config/bat/config': No such file or directory (os error 2).

Custom assets metadata

Could not read contents of '/home/xnuk/.cache/bat/metadata.yaml': No such file or directory (os error 2).

Custom assets

'/home/xnuk/.cache/bat' not found

Compile time information

  • Profile: release
  • Target triple: x86_64-unknown-linux-gnu
  • Family: unix
  • OS: linux
  • Architecture: x86_64
  • Pointer width: 64
  • Endian: little
  • CPU features: fxsr,sse,sse2
  • Host: x86_64-unknown-linux-gnu

Less version

> less --version 
less 643 (PCRE2 regular expressions)
Copyright (C) 1984-2023  Mark Nudelman

less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Home page: https://greenwoodsoftware.com/less

xnuk avatar Aug 22 '23 06:08 xnuk

I figured out the problem here. You can see it on line 261 of src/input.rs The input is being read in one line at a time or until the EOT character has been reached. Because /dev/zero is an infinite stream of zeros, it doesn't have a newline character or a EOT character, which means the first line never finishes being read and the program hangs.

johnmatthiggins avatar Aug 26 '23 19:08 johnmatthiggins

After reading a the source code of the cat commands from FreeBSD source and GNU coreutils I understand why they can handle reading from /dev/zero and bat cannot. The cat command typically reads in an exact amount of characters into it's internal buffer than prints that chunk before refilling its buffer with more characters from the file. The cat command never waits for any delimiters which is why it can handle an infinite stream of text.

The README.md does mention that bat should be a drop in replacement for cat when used non-interactively, so refactoring to support this does seem like it's within the projects goals.

This is a very intriguing problem and I would love to know what the core maintainers think should be done.

johnmatthiggins avatar Aug 28 '23 01:08 johnmatthiggins

Thanks for reporting and thanks @johnmatthiggins for investigating. It has been mentioned by a maintainer before that bat is designed to output only after receiving a \n character in the input: https://github.com/sharkdp/bat/issues/836#issuecomment-589880495

It's worth noting though that something similar was reported before and is accepted as a valid bug: https://github.com/sharkdp/bat/issues/636

I believe the syntax highlighting library we are using expects to be fed (complete) single line inputs, so I'm not sure how solvable this will turn out to be in practice...

keith-hall avatar Aug 28 '23 05:08 keith-hall