Aqui está um exemplo mínimo de funcionamento:
package main
import (
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
"github.com/fyne-io/terminal"
"log/slog"
"os"
"os/exec"
"sync"
)
func main() {
err := runMain()
if err != nil {
slog.Error(err.Error())
os.Exit(1)
}
}
func runMain() error {
wg := sync.WaitGroup{}
wg.Add(1)
term := terminal.New()
go func() {
var err error
// This works
// err = term.RunLocalShell()
// This does not work, blank screen...
cmd := exec.Command("/usr/bin/bash")
si, err := cmd.StdinPipe()
if err != nil {
slog.Error(err.Error())
os.Exit(1)
}
so, err := cmd.StdoutPipe()
if err != nil {
slog.Error(err.Error())
os.Exit(1)
}
err = cmd.Start()
if err != nil {
slog.Error(err.Error())
os.Exit(1)
}
slog.Info("started", "pid", cmd.Process.Pid)
err = term.RunWithConnection(si, so)
if err != nil {
slog.Error(err.Error())
}
wg.Done()
}()
a := app.New()
go func() {
wg.Wait()
a.Quit()
}()
w := a.NewWindow("Test")
w.SetContent(container.New(layout.NewStackLayout(), term))
w.ShowAndRun()
return nil
}
Então term.RunLocalShell()
funciona, mas a conexão manual stdout e stdin de uma chamada os.Exec para term.RunWithConnection(in, out)
não funciona. Ele exibe uma tela em branco, e não há nenhuma mensagem de erro.
O que há de errado aqui?
Posso ver que terminal.RunLocalShell chama terminal.open() e que usa github.com/creack/pty para criar um pty. No entanto, terminal.pty não é um campo público, ele não pode ser acessado de fora. Meu objetivo é executar um comando shell remotamente e exibi-lo em um emulador de terminal local. Por exemplo, o exemplo dado é realmente mínimo, na realidade stdin e stdout são pipes conectados com TCP a um processo remoto.
Se o objetivo for um sistema remoto, recomendo verificar um aplicativo SSH que escrevi usando a biblioteca de terminais fyne - ele provavelmente faz o que você precisa.
https://github.com/andydotxyz/sshterm/blob/57557c8e6ab083370f00acd21d228b0bbd692518/main.go#L170