wish
wish copied to clipboard
wish-exec has issues starting a bash shell (outputs to server stdout | error `Inappropriate ioctl for device`)
What
The wish-exec example works fine with vim but when trying to exec an interactive bash process the following occurs.
Outputs to server Stdout
Relying on bubbletea.ExecProcess
to set the default Std(in,out,err) for the *exec.Cmd results in the Stdout of the bash process being on the server's stdout.
https://github.com/charmbracelet/bubbletea/blob/v0.25.0/exec.go#L112C16-L112C22 https://github.com/charmbracelet/bubbletea/blob/v0.25.0/options.go#L35C23-L35C32 https://github.com/muesli/termenv/blob/v0.15.2/output.go#L184
Output to client Stdout but bash reports an error at startup
Explicitly setting the Std(in,out,err) to the pty.Slave
, as the makeOptions function does results in the bash process outputting to the client but displaying the following error upon startup.
https://github.com/charmbracelet/wish/blob/main/bubbletea/tea_unix.go#L22
bash: cannot set terminal process group (1632577): Inappropriate ioctl for device
bash: no job control in this shell
Ctrl+c isn't registered by shell either.
Reproduction
The following is a diff with a runnable example of this error.
diff --git a/examples/wish-exec/main.go b/examples/wish-exec/main.go
index 1137779..1dbbdcd 100644
--- a/examples/wish-exec/main.go
+++ b/examples/wish-exec/main.go
@@ -93,6 +93,32 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return vimFinishedMsg{err: err}
})
return m, cmd
+ case "f":
+ log.Info("pressed f: launching bash (server stdout)")
+ // Output shows up on server's stdout, no error messages
+ c := exec.Command("bash", "-il")
+ cmd := tea.ExecProcess(c, func(err error) tea.Msg {
+ if err != nil {
+ log.Error("bash (server stdout) finished", "error", err)
+ }
+ return vimFinishedMsg{err: err}
+ })
+ return m, cmd
+ case "b":
+ log.Info("pressed b: launching bash (client stdout)")
+ pty, _, _ := m.sess.Pty()
+ // Output shows up on client stdout, but there is an error message
+ c := exec.Command("bash", "-il")
+ c.Stdin = pty.Slave
+ c.Stdout = pty.Slave
+ c.Stderr = pty.Slave
+ cmd := tea.ExecProcess(c, func(err error) tea.Msg {
+ if err != nil {
+ log.Error("bash (client stdout) finished", "error", err)
+ }
+ return vimFinishedMsg{err: err}
+ })
+ return m, cmd
case "q", "ctrl+c":
return m, tea.Quit
}
good find, #229 should fix it 🙏