Go SSH客户端二次执行命令需按两次回车的问题及修改方案
解决Go SSH客户端循环会话二次输入需额外回车的问题
问题根源
- SSH Session未正确关闭:每次执行
session.Run()后未调用session.Close()释放资源,导致标准输入输出流的关联残留,干扰下一次输入操作。 - 重复创建输入Reader:循环内每次实例化
bufio.NewReader(os.Stdin),多次创建会引发输入缓冲区读取混乱,尤其是支持的命令执行后,Session输入流未清理,导致二次输入需要额外回车。
修复方案
- 强制关闭SSH Session:无论命令执行成功或失败,处理完成后必须关闭Session,释放相关流资源。
- 复用输入Reader:将
bufio.NewReader(os.Stdin)的初始化移到循环外,整个会话复用同一个Reader,避免缓冲区冲突。 - 清理冗余代码与错误处理:移除
os.Exit(0)后的无效break语句,同时不要忽略reader.ReadString的读取错误。
修改后的代码示例
import ( "bufio" "fmt" "os" "strings" "golang.org/x/crypto/ssh" ) var commandList = map[string]bool{ "ls": true, "ls -l": true, "date": true, } func CircularSession(c *ssh.Client) { var Cmd string // 初始化Reader移到循环外,复用实例 reader := bufio.NewReader(os.Stdin) for { session, err := c.NewSession() if err != nil { fmt.Println("create session failed:", err) continue } session.Stdout = os.Stdout session.Stdin = os.Stdin session.Stderr = os.Stderr fmt.Print("\nPlease enter the command: ") // 处理读取命令的错误 Cmd, err = reader.ReadString('\n') if err != nil { fmt.Println("read command failed: ", err) session.Close() continue } Cmd = strings.TrimSpace(Cmd) if Cmd == "exit" { session.Close() os.Exit(0) } if _, exists := commandList[Cmd]; exists { err = session.Run(Cmd) if err != nil { fmt.Println("command run failed: ", err) } } else { fmt.Println("This command is not supported.") } // 执行完成后关闭Session,释放资源 if err := session.Close(); err != nil { fmt.Println("close session failed: ", err) } } } // 调用示例 // c := sshconnect.GetSshClient() // sshconnect.CircularSession(c)
内容的提问来源于stack exchange,提问作者Bridge
相关产品推荐
相关产品推荐

