Skip to content

Latest commit

 

History

History
93 lines (73 loc) · 2.79 KB

golang_scripting.md

File metadata and controls

93 lines (73 loc) · 2.79 KB

go scripting

拿go当脚本来用主要都是执行一些批处理的操作。虽然bash也可以完成这一类工作, perl或python也和go同样好用,但可能有一些人对golang比较熟悉,碰巧golang也能完成这一类工作,所以我们也可以在这方面尝试一下。 下面我们用golang来实现一个简单的业务布署功能。我有一个小项目叫做kentucky,它编译之后生成一个二进制文件。我需要将这个二进制文件在服务器上跑起来。做这个事情需要三个步骤:(1)结束服务器上正在运行的旧版本kentucky,(2)上传当前版本的kentucy到服务器,(3)启动新版本的kentucky。

expect

expect是一个bash命令,用来实现自动和交互式任务进行通信,而无需人的干预。expect是不断发展的,随着时间的流逝,其功能越来越强大,已经成为系统管理员的的一个强大助手。

github上有一个项目使用golang提供了类似的功能,其地址是https://github.com/jamesharr/expect。

我们需要用expect来实现第一步和第三步。

下面的示例代码展示了如何实现第一步,杀死旧的进程:

package main

import (
	"fmt"
	"strings"
    "time"

	"github.com/jamesharr/expect"
)

func main() {
    // Spawn an expect process
    ssh, err := expect.Spawn("ssh", "[email protected]")
    if err != nil {
	    fmt.Println(err)
	    return
    }
    ssh.SetTimeout(10 * time.Second)
    const PROMPT = `.*#`

    // Login
    ssh.Expect(`[Pp]assword:`)
    ssh.SendMasked("876400aa") // SendMasked hides from logging
    ssh.Send("\n")
    ssh.Expect(PROMPT) // Wait for prompt

    // Run a command
    ssh.SendLn("ps -ef | grep ' ./kentu' | awk '{ print $2 }'")
    match, err := ssh.Expect(PROMPT) // Wait for prompt
    results := strings.Split(match.Before, "\n")
    var pid string
    if len(results) >= 2 {
	    fmt.Println("pid is ", results[1])
	    pid = results[1]
    } else {
	    fmt.Println("cannot find a process of this name")
	    return
    }

    ssh.SendLn("kill -9 " + pid)
    match, err = ssh.Expect(PROMPT)
    fmt.Println(match.Before)

    // Wait for EOF
    ssh.SendLn("exit")
    ssh.ExpectEOF()
}

以下代码实现第三步,即启动新的子服务进程:

func step3() { // start process
	// Spawn an expect process
	ssh, err := expect.Spawn("ssh", "[email protected]")
	if err != nil {
		fmt.Println(err)
		return
	}
	ssh.SetTimeout(10 * time.Second)
	const PROMPT = `.*#`

	// Login
	ssh.Expect(`[Pp]assword:`)
	ssh.SendMasked("876400aa") // SendMasked hides from logging
	ssh.Send("\n")
	ssh.Expect(PROMPT) // Wait for prompt

	// Run a command
	ssh.SendLn("cd /alidata/server/go1.4.2/go/gopath/src/kentucky")
	ssh.SendLn("nohup ./kentucky &")
	match, _ := ssh.Expect(PROMPT)
	fmt.Println(match.Before)

}```