目录
1.什么是自动应答?
自动应答是shell脚本过程中常见的一种方式。expect就是一种自动应答的工具。主要由expect-send决定。
2.自动应答有哪些工具实现方式?自动应答的使用场景有哪些?
expect 的安装可以通过yum安装或者源码安装,也可以使用一些类似go-expect的工具。
其中go-expect工具如下
package main
import (
"fmt"
expect "github.com/google/goexpect"
"github.com/google/goterm/term"
"log"
"os"
"regexp"
"time"
)
const (
timeout = 10000 * time.Millisecond
)
var (
promptRE = regexp.MustCompile("%")
)
func main() {
// 获取命令行参数
fmt.Println("命令行参数数量:", len(os.Args))
cmd := os.Args[1]
fmt.Println("cmd:", cmd)
e, _, err := expect.Spawn(cmd, -1)
if err != nil {
log.Fatal(err)
return
}
defer e.Close()
lens := len(os.Args)
for i := 2; i < lens; i += 2 {
expectStr := os.Args[i]
sendStr := os.Args[i+1]
fmt.Printf("expectStr:%v sendStr:%v \n", os.Args[i], os.Args[i+1])
expectRE := regexp.MustCompile(expectStr)
if expectRE == nil {
return
}
eStr := e.String()
fmt.Println("eStr:", eStr)
s, strings, err := e.Expect(expectRE, timeout)
if err != nil {
fmt.Printf("err: %s \n", err.Error())
fmt.Printf("out: %s \n", s)
fmt.Printf("match: %v \n ", strings)
return
}
fmt.Printf("out:%s \n", s)
fmt.Printf("match:%v \n", strings)
if err := e.Send(sendStr+"\n"); err != nil {
fmt.Printf("err:%s", err.Error())
return
}
}
result, arrStr, err := e.Expect(promptRE, timeout)
if err := e.Send("exit\n"); err != nil {
fmt.Printf("err:%s \n", err.Error())
fmt.Printf("out:%s \n", result)
fmt.Printf("match:%v \n", arrStr)
return
}
fmt.Printf("out:%s ", result)
fmt.Printf("match:%v ", arrStr)
fmt.Println("===============================")
fmt.Println(term.Greenf("%s: result: %s\n", cmd, result))
}
自动应答的主要使用场景有免密登录和ssh-key的秘钥生成等
先编译上面的xexpect.go文件,生成xexpect二进制文件。免密登录和ssh-keygen的代码生成如下:
生成秘钥
xexpect "ssh-keygen -t rsa" ".*(/root/.ssh/id_rsa)" "" ".*(empty for no passphrase)" "" ".*again" "" ".*(y/n)" "y"
免密登录
xexpect 'ssh-copy-id root@192.168.180.135' ".*yes/no" "yes" ".*password" "123456"
参考博客
1.https://www.cnblogs.com/operationhome/p/9154055.html