使用Golang实现linux管道处理

在项目中遇到了一个和其他项目整合的一个需求,我们的虚拟机是以UUID的方式创建的,名称是存储在主节点的数据库中,整合的平台是使用ssh的方式到我们的服务器上进行数据采集,但是采集的虚拟机名称是UUID,并不是虚拟机的名称,这时候就需要进行转换UUID到VmName。

鉴于对方平台的命令较多,且后期可能会有改的可能,但是需求只有将UUID替换成Name的需求,所以经过考虑我们采用以原有命令结果作为管道输入,程序进行替换,然后再输出的方式进行。

linux的管道内容是通过os.Stdin中读取的,我们可以通过像普通文件一样操作os.Stdin,下面是管道读取的程序示例:

package main

import (
    "bufio"
    "fmt"
    "log"
    "os"
)

func main() {
    fileInfo, _ := os.Stdin.Stat()
    if (fileInfo.Mode() & os.ModeNamedPipe) != os.ModeNamedPipe {
        log.Fatal("The command is intended to work with pipes.")
    }
    s := bufio.NewScanner(os.Stdin)
    for s.Scan() {
        fmt.Println(s.Text())
    }
}

上面这个程序是用来获取管道输入然后再输出出来的过程,现在加入替换UUID的示例:

package main

import (
   "bufio"
   "fmt"
   "log"
   "os"
   "strings"
)

func main() {
   fileInfo, _ := os.Stdin.Stat()
   // 判定是否为管道输入
   if (fileInfo.Mode() & os.ModeNamedPipe) != os.ModeNamedPipe {
      log.Fatal("The command is intended to work with pipes.")
   }
   s := bufio.NewScanner(os.Stdin)
   // outputString 用来存储管道输入的原始字符串,并后期进行替换
   outputString := ""
   for s.Scan() {
      outputString += s.Text()+"\n"
   }
   // getUuidNameMap 函数用来获取UUID和Name的对应关系
   uuidMap,err := getUuidNameMap()
   if err != nil{
      // 这里的设计哲学是:如果管道处理函数报错了,那将原有输入直接输出
      fmt.Println(outputString)
   }
   for uuid,name := range uuidMap{
      // UUID 替换为 Name, 全文无限替换
      outputString = strings.Replace(outputString,uuid,name,-1)
   }
   // 最后输出变更后的字符串
   fmt.Println(outputString)
}

func getUuidNameMap()(uuidMap map[string]string,err error){
   // 增加获取对应关系的处理逻辑
   return
}

其中getUuidNameMap逻辑需要根据各自需求进行处理。

这里只是举了个例子使用Golang进行管道处理,管道能处理的事情还很多,从另一个方面也说明Golang语言作为运维语言是十分快捷高效的。

About the author

liuyuhang

View all posts

匿名进行回复 取消回复