Golang - 执行 shell 脚本,并实时按行打印 shell 脚本输出信息

原文链接:https://blog.csdn.net/flyfreelyit/article/details/103697013

测试代码地址:https://github.com/kirinlabs/execshell

Golang 执行 shell 脚本,不接收返回值

Go 复制代码
// 返回一个 cmd 对象
cmd := exec.Command("sh", "-c", "./scripts/curl.sh")
 
// 如果只执行命令,不接收返回值
cmd.Run()

Run(),命令其实是调用了 cmd.Start()和 cmd.Wait()两个方法,只返回一个 error 对象

Golang 执行 shell脚本,接收返回值

Go 复制代码
// 返回一个 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 脚本的中每条命令的输出日志信息,便于查看任务进度等

Go 复制代码
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 对日志的实时输出

Go 复制代码
#!/bin/bash
 
#print time
for((i=0;i<10;i++))
do
    sleep 1
    echo $(date +"%Y-%m-%d %H:%M:%S")
done
相关推荐
llz_1121 小时前
web-第二次课后作业
前端·后端·web
红尘散仙7 小时前
我把终端小说阅读器接上了 AI Agent:TRNovel 现在能用 skill 生成书源了
人工智能·后端·rust
卷毛的技术笔记8 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
isyangli_blog8 小时前
OpenDayLight (Carbon 版本) 启动与组件安装
开发语言·php
vb2008118 小时前
FastAPI APIRouter
开发语言·python
Benszen8 小时前
KVM虚拟化解决方案
开发语言·perl
会编程的土豆9 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
東雪木9 小时前
多线程与并发编程 专属复习笔记
java·开发语言·笔记·java面试
喵个咪9 小时前
GoWind Toolkit Go后端代码生成 完整全流程实战
后端·go·orm
杨充9 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法