Process Golang从终端进程写入输入并获取输出
我有一个关于如何从终端子进程(如ssh)发送输入和接收输出的问题。python中的一个示例如下: 我在Golang找不到一个简单的例子,与上面的工作原理类似 在Golang,我想做类似的事情,但似乎不起作用:Process Golang从终端进程写入输入并获取输出,process,terminal,go,pty,Process,Terminal,Go,Pty,我有一个关于如何从终端子进程(如ssh)发送输入和接收输出的问题。python中的一个示例如下: 我在Golang找不到一个简单的例子,与上面的工作原理类似 在Golang,我想做类似的事情,但似乎不起作用: cmd := exec.Command("ssh", "user@x.x.x.x") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr stdin, _ := cmd.StdinPipe() stdin.W
cmd := exec.Command("ssh", "user@x.x.x.x")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
stdin, _ := cmd.StdinPipe()
stdin.Write([]byte("password\n"))
cmd.Run()
但是,;我不知道如何在go中执行此操作,因为每次执行此ssh命令时,我只能获得输出。我无法从密码中自动输入密码。
有人有向终端进程(如ssh)写入数据的例子吗?如果是,请分享 多亏了上面的评论,我才能够使用密码获得ssh访问权限。我使用了golang的SSHAPI库。这相当简单,因为我遵循以下示例: 具体而言:
func ExampleDial() {
// An SSH client is represented with a ClientConn. Currently only
// the "password" authentication method is supported.
//
// To authenticate with the remote server you must pass at least one
// implementation of AuthMethod via the Auth field in ClientConfig.
config := &ClientConfig{
User: "username",
Auth: []AuthMethod{
Password("yourpassword"),
},
}
client, err := Dial("tcp", "yourserver.com:22", config)
if err != nil {
panic("Failed to dial: " + err.Error())
}
// Each ClientConn can support multiple interactive sessions,
// represented by a Session.
session, err := client.NewSession()
if err != nil {
panic("Failed to create session: " + err.Error())
}
defer session.Close()
// Once a Session is created, you can execute a single command on
// the remote side using the Run method.
var b bytes.Buffer
session.Stdout = &b
if err := session.Run("/usr/bin/whoami"); err != nil {
panic("Failed to run: " + err.Error())
}
fmt.Println(b.String())
}
由于上面的评论,我能够使用密码获得ssh访问权限。我使用了golang的SSHAPI库。这相当简单,因为我遵循以下示例: 具体而言:
func ExampleDial() {
// An SSH client is represented with a ClientConn. Currently only
// the "password" authentication method is supported.
//
// To authenticate with the remote server you must pass at least one
// implementation of AuthMethod via the Auth field in ClientConfig.
config := &ClientConfig{
User: "username",
Auth: []AuthMethod{
Password("yourpassword"),
},
}
client, err := Dial("tcp", "yourserver.com:22", config)
if err != nil {
panic("Failed to dial: " + err.Error())
}
// Each ClientConn can support multiple interactive sessions,
// represented by a Session.
session, err := client.NewSession()
if err != nil {
panic("Failed to create session: " + err.Error())
}
defer session.Close()
// Once a Session is created, you can execute a single command on
// the remote side using the Run method.
var b bytes.Buffer
session.Stdout = &b
if err := session.Run("/usr/bin/whoami"); err != nil {
panic("Failed to run: " + err.Error())
}
fmt.Println(b.String())
}
这是上述示例的修改/完整版本 首先获取
终端
包,通过获取golang.org/x/crypto/ssh
package main
import (
"bufio"
"bytes"
"fmt"
"os"
"strings"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/terminal"
)
func main() {
if len(os.Args) < 3 {
usage := "\n./remote-ssh {host} {port}"
fmt.Println(usage)
} else {
host := os.Args[1]
port := os.Args[2]
username, password := credentials()
config := &ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{
ssh.Password(password),
},
}
connectingMsg := fmt.Sprintf("\nConnecting to %s:%v remote server...", host, port)
fmt.Println(connectingMsg)
hostAddress := strings.Join([]string{host, port}, ":")
// fmt.Println("Host add %s ", hostAddress)
client, err := ssh.Dial("tcp", hostAddress, config)
if err != nil {
panic("Failed to dial: " + err.Error())
}
for {
session, err := client.NewSession()
if err != nil {
panic("Failed to create session: " + err.Error())
}
defer session.Close()
// Once a Session is created, can execute a single command on remote side
var cmd string
str := "\nEnter command (e.g. /usr/bin/whoami OR enter 'exit' to return) : "
fmt.Print(str)
fmt.Scanf("%s", &cmd)
if cmd == "exit" || cmd == "EXIT" {
break
}
s := fmt.Sprintf("Wait for command '%s' run and response...", cmd)
fmt.Println(s)
var b bytes.Buffer
session.Stdout = &b
if err := session.Run(cmd); err != nil {
panic("Failed to run: " + err.Error())
}
fmt.Println(b.String())
}
}
}
func credentials() (string, string) {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter Username: ")
username, _ := reader.ReadString('\n')
fmt.Print("Enter Password: ")
bytePassword, err := terminal.ReadPassword(0)
if err != nil {
panic(err)
}
password := string(bytePassword)
return strings.TrimSpace(username), strings.TrimSpace(password)
}
主程序包
进口(
“布菲奥”
“字节”
“fmt”
“操作系统”
“字符串”
“golang.org/x/crypto/ssh”
“golang.org/x/crypto/ssh/terminal”
)
func main(){
如果len(os.Args)<3{
用法:=“\n./远程ssh{host}{port}”
fmt.Println(使用)
}否则{
主机:=os.Args[1]
端口:=os.Args[2]
用户名、密码:=凭据()
config:=&ssh.ClientConfig{
用户:用户名,
Auth:[]ssh.AuthMethod{
ssh.Password(密码),
},
}
ConnectionMsg:=fmt.Sprintf(“\n正在连接到%s:%v远程服务器…”,主机,端口)
fmt.Println(连接消息)
主机地址:=strings.Join([]字符串{host,port},“:”)
//fmt.Println(“主机添加%s”,主机地址)
客户端,错误:=ssh.Dial(“tcp”,主机地址,配置)
如果错误!=零{
死机(“拨号失败:+err.Error())
}
为了{
会话,错误:=client.NewSession()
如果错误!=零{
死机(“创建会话失败:+err.Error())
}
延迟会话。关闭()
//一旦创建了会话,您就可以在远程端执行单个命令
var cmd字符串
str:=“\n输入命令(例如/usr/bin/whoami或输入'exit'返回):”
格式打印(str)
格式扫描(“%s”和cmd)
如果cmd==“退出”| | cmd==“退出”{
打破
}
s:=fmt.Sprintf(“等待命令“%s”运行并响应…”,cmd)
fmt.Println(s)
VARBytes.Buffer
session.Stdout=&b
如果错误:=session.Run(cmd);错误!=nil{
死机(“无法运行:+err.Error())
}
fmt.Println(b.String())
}
}
}
func凭据()(字符串,字符串){
reader:=bufio.NewReader(os.Stdin)
打印(“输入用户名:”)
用户名:=reader.ReadString('\n')
打印(“输入密码:”)
bytePassword,错误:=终端。读取密码(0)
如果错误!=零{
恐慌(错误)
}
密码:=字符串(bytePassword)
返回strings.TrimSpace(用户名),strings.TrimSpace(密码)
}
这是上述示例的修改/完整版本 首先获取
终端
包,通过获取golang.org/x/crypto/ssh
package main
import (
"bufio"
"bytes"
"fmt"
"os"
"strings"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/terminal"
)
func main() {
if len(os.Args) < 3 {
usage := "\n./remote-ssh {host} {port}"
fmt.Println(usage)
} else {
host := os.Args[1]
port := os.Args[2]
username, password := credentials()
config := &ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{
ssh.Password(password),
},
}
connectingMsg := fmt.Sprintf("\nConnecting to %s:%v remote server...", host, port)
fmt.Println(connectingMsg)
hostAddress := strings.Join([]string{host, port}, ":")
// fmt.Println("Host add %s ", hostAddress)
client, err := ssh.Dial("tcp", hostAddress, config)
if err != nil {
panic("Failed to dial: " + err.Error())
}
for {
session, err := client.NewSession()
if err != nil {
panic("Failed to create session: " + err.Error())
}
defer session.Close()
// Once a Session is created, can execute a single command on remote side
var cmd string
str := "\nEnter command (e.g. /usr/bin/whoami OR enter 'exit' to return) : "
fmt.Print(str)
fmt.Scanf("%s", &cmd)
if cmd == "exit" || cmd == "EXIT" {
break
}
s := fmt.Sprintf("Wait for command '%s' run and response...", cmd)
fmt.Println(s)
var b bytes.Buffer
session.Stdout = &b
if err := session.Run(cmd); err != nil {
panic("Failed to run: " + err.Error())
}
fmt.Println(b.String())
}
}
}
func credentials() (string, string) {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter Username: ")
username, _ := reader.ReadString('\n')
fmt.Print("Enter Password: ")
bytePassword, err := terminal.ReadPassword(0)
if err != nil {
panic(err)
}
password := string(bytePassword)
return strings.TrimSpace(username), strings.TrimSpace(password)
}
主程序包
进口(
“布菲奥”
“字节”
“fmt”
“操作系统”
“字符串”
“golang.org/x/crypto/ssh”
“golang.org/x/crypto/ssh/terminal”
)
func main(){
如果len(os.Args)<3{
用法:=“\n./远程ssh{host}{port}”
fmt.Println(使用)
}否则{
主机:=os.Args[1]
端口:=os.Args[2]
用户名、密码:=凭据()
config:=&ssh.ClientConfig{
用户:用户名,
Auth:[]ssh.AuthMethod{
ssh.Password(密码),
},
}
ConnectionMsg:=fmt.Sprintf(“\n正在连接到%s:%v远程服务器…”,主机,端口)
fmt.Println(连接消息)
主机地址:=strings.Join([]字符串{host,port},“:”)
//fmt.Println(“主机添加%s”,主机地址)
客户端,错误:=ssh.Dial(“tcp”,主机地址,配置)
如果错误!=零{
死机(“拨号失败:+err.Error())
}
为了{
会话,错误:=client.NewSession()
如果错误!=零{
死机(“创建会话失败:+err.Error())
}
延迟会话。关闭()
//一旦创建了会话,您就可以在远程端执行单个命令
var cmd字符串
str:=“\n输入命令(例如/usr/bin/whoami或输入'exit'返回):”
格式打印(str)
格式扫描(“%s”和cmd)
如果cmd==“退出”| | cmd==“退出”{
打破
}
s:=fmt.Sprintf(“等待命令“%s”运行并响应…”,cmd)
fmt.Println(s)
VARBytes.Buffer
session.Stdout=&b
如果错误:=session.Run(cmd);错误!=nil{
死机(“无法运行:+err.Error())
}
fmt.Println(b.String())
}
}
}
func凭据()(字符串,字符串){
reader:=bufio.NewReader(os.Stdin)
打印(“输入用户名:”)
用户名:=reader.ReadString('\n')
打印(“输入密码:”)
bytePassword,错误:=终端。读取密码(0)
如果错误!=零{
恐慌(错误)
}
密码:=字符串(bytePassword)
返回strings.TrimSpace(用户名),strings.TrimSpace(密码)
}
使用
ssh
您无法轻松做到这一点,因为它将拒绝从stdin