wish icon indicating copy to clipboard operation
wish copied to clipboard

wish-exec has issues starting a bash shell (outputs to server stdout | error `Inappropriate ioctl for device`)

Open ghthor opened this issue 1 year ago • 1 comments

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
 		}

Peek 2024-01-19 20-18

ghthor avatar Jan 20 '24 01:01 ghthor

good find, #229 should fix it 🙏

caarlos0 avatar Jan 22 '24 13:01 caarlos0