bubbletea icon indicating copy to clipboard operation
bubbletea copied to clipboard

Bubbletea apps hang if invoked within shell process substitution

Open willmurphyscode opened this issue 2 years ago • 0 comments

Describe the bug Example from this repo:

# works
go run tutorials/commands/main.go
# hangs forever
cat <(go run tutorials/commands/main.go)

Setup Please complete the following information along with version numbers, if applicable.

  • OS [e.g. Ubuntu, macOS] - macOS Ventura 13.5
  • Shell [e.g. zsh, fish] - tested in zsh (zsh 5.9 (x86_64-apple-darwin22.0) and bash (GNU bash, version 3.2.57(1)-release (arm64-apple-darwin22))
  • Terminal Emulator [e.g. kitty, iterm] - tested in iTerm2 3.4.19
  • Terminal Multiplexer [e.g. tmux] - none in use

To Reproduce Steps to reproduce the behavior:

git clone [email protected]:charmbracelet/bubbletea.git /tmp/btea-bug
cd /tmp/btea-bug
go build -o repro tutorials/commands/main.go
./repro
echo 'cat <(./repro) is about to hang'
cat <(./repro)

Source Code Please include source code if needed to reproduce the behavior.

No additional source code needed, but I believe there are two places in bubble tea where this hangs, maybe more:

  • https://github.com/charmbracelet/bubbletea/blob/91dd1200733714c4fb7bc7ffb24af2c35cc2f111/tty.go#L23
  • https://github.com/charmbracelet/bubbletea/blob/91dd1200733714c4fb7bc7ffb24af2c35cc2f111/tty.go#L29

I'm especially interested in the case where WithOutput(os.Stderr) is added here: https://github.com/charmbracelet/bubbletea/blob/91dd1200733714c4fb7bc7ffb24af2c35cc2f111/tutorials/commands/main.go#L74

Expected behavior

Either:

  1. Bubbletea detects that the invocation is part of process substitution and falls back to interacting with outputs in a way that doesn't hang
  2. Bubbletea documents how to detect and avoid this hang (we could just check whether stdout is a pipe or a device, but we'd like to have a bubbletea UI on stderr while stdout is redirected. We have this working today, but can't detect the process substitution, so we have a place where the UI hangs unexpectedly.)

Apologies if you already have this documented somewhere; I haven't been able to find it.

Additional context

I found this while investigating this: https://github.com/anchore/syft/issues/1439#issuecomment-1659113437

Note: We are using WithOutput(os.Stderr) when calling NewProgram. Invocations like syft whatever | grep foo work fine with bubbletea going to stderr, but invocations like diff <(syft whatever) <(syft the-other) hang.

I'd be happy to help with the investigation and the fix - just let me know how I can help!

willmurphyscode avatar Aug 02 '23 19:08 willmurphyscode