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
相关推荐
郝学胜-神的一滴41 分钟前
Python 高级编程 026:内置数据结构之骈文纵论
开发语言·数据结构·python·程序人生·软件工程
陈随易7 小时前
FFmpeg 9.0 发布,代号 Lei,音视频处理再升级
前端·后端·程序员
隐积8 小时前
3.1.7.Qt容器大家族(3):QVariant——万能盒子
开发语言·qt
凌虚10 小时前
面向 MySQL 用户的 PostgreSQL 快速上手指南
数据库·后端·架构
名字还没想好☜11 小时前
Next.js ‘use client‘ 到底加在哪:Server/Client Components 边界与常见报错
开发语言·前端·javascript·react·next.js
IT_陈寒12 小时前
Vite静态资源引用这个坑我踩得有点疼
前端·人工智能·后端
初级代码游戏12 小时前
iOS开发 Swift 速记1:变量和基本数据类型
开发语言·ios·swift
前端开发张小七12 小时前
Java 学习笔记 · 第一课:基础语法与核心概念
java·后端
海盗123412 小时前
微软技术周报 ——2026-08-03
后端·python·microsoft·c#·.netcore
沙湖遇雨12 小时前
6. Pipeline 的生命周期
后端