摘要: 在工作中時常需要登錄服務器做一系列操作,每次輸入ssh xxx總是很麻煩。這時候為什么不考慮寫一個通用的小腳本呢?
go語言是一門新興語言,能夠在很多地方發揮總用。初學go語言,做了這么一個小工具,也算是練練手了。
這個小程序實現的功能是從用戶指定的文件中讀取相關配置,然后根據用戶指令執行相關操作。
代碼如下:
package main import ( "fmt" "golang.org/x/crypto/ssh" "os" "io" "bufio" "encoding/csv" "strings" "container/list" ) var ( num int ) func main() { if len(os.Args) == 1{ fmt.Println("請輸入文件名參數") return } list := listNode(os.Args[1]) fmt.Println("請選擇執行的語句") fmt.Scanln(&num) if num <= list.Len(){ fmt.Println("您選擇的是 ", num) ssh_to_do(list,num) }else { fmt.Println("您輸入有誤! num:",num) } } func ssh_to_do(list *list.List, num int) { if num != 0 { i := 1 for node := list.Front(); node != nil; node = node.Next() { if i == num { switch value := node.Value.(type) { case BatchNode: SSH_do(value.User, value.Password, value.Ip_port, value.Cmd) } } i++ } } else { for node := list.Front(); node != nil; node = node.Next() { switch value := node.Value.(type) { case BatchNode: SSH_do(value.User, value.Password, value.Ip_port, value.Cmd) } } } } func listNode(fileName string) *list.List { list := readNode(fileName) fmt.Printf("共計 %d 條數據\n", list.Len()) i := 1 for node := list.Front(); node != nil; node = node.Next() { switch value := node.Value.(type) { case BatchNode: fmt.Println(i, " ", value.String()) } i++ } return list } func SSH_do(user, password, ip_port string, cmd string) { PassWd := []ssh.AuthMethod{ssh.Password(password)} Conf := ssh.ClientConfig{User: user, Auth: PassWd} Client, _ := ssh.Dial("tcp", ip_port, &Conf) defer Client.Close() for { command := cmd if session, err := Client.NewSession(); err == nil { defer session.Close() session.Stdout = os.Stdout session.Stderr = os.Stderr session.Run(command) break } } } type BatchNode struct { User string Password string Ip_port string Cmd string } func (batchNode *BatchNode) String() string { return "ssh " + batchNode.User + "@" + batchNode.Ip_port + " with password: " + batchNode.Password + " and run: " + batchNode.Cmd } func readNode(fileName string) *list.List { inputFile, err := os.Open(fileName) if err != nil { fmt.Printf("在打開文件的時候出現錯誤\n文件存在嗎?\n有權限嗎?\n") return list.New() } defer inputFile.Close() batchNodeList := list.New() inputReader := bufio.NewReader(inputFile) for { inputString, err := inputReader.ReadString('\n') r := csv.NewReader(strings.NewReader(string(inputString))) for { record, err := r.Read() if err == io.EOF { break } if err != nil { fmt.Println("error !!! ", err) continue } batchNode := BatchNode{record[0], record[1], record[2], record[3]} batchNodeList.PushBack(batchNode) } if err == io.EOF { break } } return batchNodeList }
我的文件內容是:
gavin,xxxx,192.168.1.128:22,echo ok1 >>a.data gavin,xxxx,192.168.1.128:22,echo ok2 >>a.data gavin,xxxx,192.168.1.128:22,echo ok3 >>a.data gavin,xxxx,192.168.1.128:22,echo ok4 >>a.data
小程序限制使用csv格式的文件內容,這種格式也方便被excel處理
運行的結果如下:
共計 4 條數據
1 ssh gavin@192.168.1.128:22 with password: root and run: echo ok1 >>a.data
2 ssh gavin@192.168.1.128:22 with password: root and run: echo ok2 >>a.data
3 ssh gavin@192.168.1.128:22 with password: root and run: echo ok3 >>a.data
4 ssh gavin@192.168.1.128:22 with password: root and run: echo ok4 >>a.data
請選擇執行的語句
1
您選擇的是 1
去線上查看:
![]()
如果輸入的是0,則執行所有配置項。也就是說如果有固定執行的任務,可以很方便地批量去操控了。
https://my.oschina.net/jiangmitiao/blog/753883
