golang实现跨平台scp批量群发文件

前端之家收集整理的这篇文章主要介绍了golang实现跨平台scp批量群发文件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
  1. package main
  2.  
  3. import (
  4. "bufio"
  5. "flag"
  6. "fmt"
  7. "io"
  8. "os"
  9. "path/filepath"
  10. "strings"
  11.  
  12. "github.com/czxichen/AutoWork/tools/split"
  13. "golang.org/x/crypto/ssh"
  14. )
  15.  
  16. var (
  17. passwd = flag.String("p","","-p passwd 指定密码.")
  18. user = flag.String("u","root","-u root 指定登录用户.")
  19. cfg = flag.String("c","serverlist","-c serverlist 指定serverlist")
  20. ip_port = flag.String("i","-i ip:port 指定目标机器的IP端口,必须和-p结合使用否则不生效.")
  21. dpath = flag.String("d","-d /tmp/20160531.zip 指定发送到的路径,不能为空.")
  22. spath = flag.String("s","-s 20160531.zip 指定要发送文件的路径,不能为空.")
  23. )
  24.  
  25. func main() {
  26. flag.Parse()
  27.  
  28. if *dpath == "" || *spath == "" {
  29. flag.PrintDefaults()
  30. os.Exit(1)
  31. }
  32.  
  33. File,err := os.Open(*spath)
  34. if err != nil {
  35. fmt.Println("打开文件失败:",err)
  36. os.Exit(1)
  37. }
  38. info,_ := File.Stat()
  39. defer File.Close()
  40.  
  41. if *ip_port != "" && *passwd != "" {
  42. Client,err := dail(*user,*passwd,*ip_port)
  43. if err != nil {
  44. fmt.Printf("连接%s失败.\n",err)
  45. os.Exit(1)
  46. }
  47. scp(Client,File,info.Size(),*dpath)
  48. return
  49. }
  50. var list [][]string
  51. ok := (*passwd != "" && *ip_port == "")
  52. list = config(*cfg,ok)
  53. if len(list) <= 0 {
  54. fmt.Println("serverlist 不能为空.")
  55. os.Exit(1)
  56. }
  57. for _,v := range list {
  58. if ok {
  59. *ip_port = v[0]
  60. } else {
  61. *user = v[0]
  62. *passwd = v[1]
  63. *ip_port = v[2]
  64. }
  65. Client,err)
  66. continue
  67. }
  68. scp(Client,*dpath)
  69. }
  70. }
  71.  
  72. func dail(user,password,ip_port string) (*ssh.Client,error) {
  73. PassWd := []ssh.AuthMethod{ssh.Password(password)}
  74. Conf := ssh.ClientConfig{User: user,Auth: PassWd}
  75. return ssh.Dial("tcp",ip_port,&Conf)
  76. }
  77.  
  78. func scp(Client *ssh.Client,File io.Reader,size int64,path string) {
  79. filename := filepath.Base(path)
  80. dirname := strings.Replace(filepath.Dir(path),"\\","/",-1)
  81. defer Client.Close()
  82.  
  83. session,err := Client.NewSession()
  84. if err != nil {
  85. fmt.Println("创建Session失败:",err)
  86. return
  87. }
  88. go func() {
  89. w,_ := session.StdinPipe()
  90. fmt.Fprintln(w,"C0644",size,filename)
  91. io.CopyN(w,size)
  92. fmt.Fprint(w,"\x00")
  93. w.Close()
  94. }()
  95.  
  96. if err := session.Run(fmt.Sprintf("/usr/bin/scp -qrt %s",dirname)); err != nil {
  97. fmt.Println("执行scp命令失败:",err)
  98. session.Close()
  99. return
  100. } else {
  101. fmt.Printf("%s 发送成功.\n",Client.RemoteAddr())
  102. session.Close()
  103. }
  104.  
  105. if session,err = Client.NewSession(); err == nil {
  106. defer session.Close()
  107. buf,err := session.Output(fmt.Sprintf("/usr/bin/md5sum %s",path))
  108. if err != nil {
  109. fmt.Println("检查md5失败:",err)
  110. return
  111. }
  112. fmt.Printf("%s 的MD5:\n%s\n",Client.RemoteAddr(),string(buf))
  113. }
  114. }
  115.  
  116. func config(path string,ok bool) (list [][]string) {
  117. File,err := os.Open(path)
  118. if err != nil {
  119. fmt.Printf("打开配置文件失败:%s\n",err)
  120. os.Exit(1)
  121. }
  122. defer File.Close()
  123. buf := bufio.NewReader(File)
  124. for {
  125. line,_,err := buf.ReadLine()
  126. if err != nil {
  127. break
  128. }
  129. str := strings.TrimSpace(string(line))
  130. strs := split.Split(str)
  131. if ok {
  132. if len(strs) != 1 {
  133. continue
  134. }
  135. } else {
  136. if len(strs) != 3 {
  137. continue
  138. }
  139. }
  140. list = append(list,strs)
  141. }
  142. return
  143. }

猜你在找的Go相关文章