在项目中遇到了一个和其他项目整合的一个需求,我们的虚拟机是以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语言作为运维语言是十分快捷高效的。