原文链接:https://blog.csdn.net/flyfreelyit/article/details/103697013
测试代码地址:https://github.com/kirinlabs/execshell
Golang 执行 shell 脚本,不接收返回值
// 返回一个 cmd 对象
cmd := exec.Command("sh", "-c", "./scripts/curl.sh")
?
// 如果只执行命令,不接收返回值
cmd.Run()
Run(),命令其实是调用了 cmd.Start()和 cmd.Wait()两个方法,只返回一个 error 对象
Golang 执行 shell脚本,接收返回值
// 返回一个 cmd 对象
cmd := exec.Command("sh", "-c", "./scripts/curl.sh")
?
// 收返回值[]byte, error
b,er:= cmd.Output()
?
log.Pringln(string(b))
? ? ? ? 返回值就是 shell 脚本打印的日志信息,但这样有一个缺点,golang 接收 shell 脚本的打印结果,必须要等待 shell 脚本全部执行完成才能一次性返回
Golang 执行 shell脚本,并实时打印 shell 脚本输出日志信息
实际业务比如:异步任务调度系统、自动发布系统等都有可能需要 shell 脚本的配合来完成,就需要实时打印 shell 脚本的中每条命令的输出日志信息,便于查看任务进度等
package main
?
import (
?? ?"fmt"
?? ?"io"
?? ?"log"
?? ?"os/exec"
?? ?"strings"
)
?
func asyncLog(reader io.ReadCloser) error {
?? ?cache := ""
?? ?buf := make([]byte, 1024, 1024)
?? ?for {
?? ??? ?num, err := reader.Read(buf)
?? ??? ?if err != nil {
?? ??? ??? ?if err == io.EOF || strings.Contains(err.Error(), "closed") {
?? ??? ??? ??? ?err = nil
?? ??? ??? ?}
?? ??? ??? ?return err
?? ??? ?}
?? ??? ?if num > 0 {
?? ??? ??? ?oByte := buf[:num]
?? ??? ??? ?h.logInfo = append(h.logInfo, oByte...)
?? ??? ??? ?oSlice := strings.Split(string(oByte), "\n")
?? ??? ??? ?line := strings.Join(oSlice[:len(oSlice)-1], "\n")
?? ??? ??? ?fmt.Printf("%s%s\n", cache, line)
?? ??? ??? ?cache = oSlice[len(oSlice)-1]
?? ??? ?}
?? ?}
?? ?return nil
}
?
func execute() error {
?? ?cmd := exec.Command("sh", "-c", "./scripts/curl.sh")
?
?? ?stdout, _ := cmd.StdoutPipe()
?? ?stderr, _ := cmd.StderrPipe()
?
?? ?if err := cmd.Start(); err != nil {
?? ??? ?log.Printf("Error starting command: %s......", err.Error())
?? ??? ?return err
?? ?}
?
?? ?go asyncLog(stdout)
?? ?go asyncLog(stderr)
?
?? ?if err := cmd.Wait(); err != nil {
?? ??? ?log.Printf("Error waiting for command execution: %s......", err.Error())
?? ??? ?return err
?? ?}
?
?? ?return nil
}
?
func main(){
?? ?execute()
}
shell脚本,每秒打印时间,观察 Golang 对日志的实时输出
#!/bin/bash
?
#print time
for((i=0;i<10;i++))
do
? ? sleep 1
? ? echo $(date +"%Y-%m-%d %H:%M:%S")
done