刘沙河 刘沙河
首页
  • Go语言基础

    • 数据类型
    • 反射
    • Go指针
  • Go语言进阶

    • go泛型
    • go条件编译
    • cgo教程
    • Go协程调度原理及GPM模型
    • Go内存管理
    • Go垃圾回收机制
    • Go语言内存对齐
  • Go语言实现原理

    • channel 实现原理
    • slice 实现原理
    • map 实现原理
    • sync.Mutex 实现原理
    • 乐观锁CAS 实现原理
    • singlefight 实现原理
  • gin框架

    • gin中间件原理
    • gin路由原理
  • gorm

    • GORM介绍和使用
    • GORM_CURD操作指南
  • go测试

    • benchmark基准测试
    • pprof 性能分析
  • python进阶

    • Numpy&Pandas
    • celery分布式任务队列
  • Django

    • Django 常见命令
    • middleware中间件
    • Django缓存系统
    • Django信号系统
    • Django REST Framework
  • Flask

    • Flask基础知识总结
    • Flask-SQLAlchemy
  • 爬虫

    • aiohttp
    • scrapy框架
  • Mysql

    • Mysql存储引擎和索引
    • MySQL主从复制
    • Mysql读写分离
    • 数据库分库分表
    • Mysql锁
    • Mysql事务和MVCC原理
    • 分库分表带来的读扩散问题
  • Redis

    • redis基础和数据类型
    • redis主从架构
    • redis哨兵架构
    • redis集群模式
    • 如何保证缓存和数据库双写一致
    • redis底层数据结构
    • redis分布式锁
  • Elasticsearch

    • es基本概念
    • es基础语法
    • es倒排索引
  • etcd

    • Go操作etcd
    • Raft原理
    • etcd分布式锁
  • kafka

    • 消息队列MQ总结
    • kafka 概述及原理
    • kafka 消费问题记录
    • 零拷贝技术
    • kafka分区规范
  • RabbitMQ

    • rabbitMQ基础
    • Go操作rabbitmq
  • RocketMQ

    • 可靠消息队列 rocketMQ
  • Http&Https

    • http&https
    • TCP和UDP
    • Ping 原理
  • RPC

    • RPC初识
    • grpc初识和实现
  • gRPC

    • grpc 初识
    • grpc 上下文 metadata
    • grpc 健康检查
    • grpc keepalive
    • grpc 命名解析
    • grpc 中间件&拦截器
    • grpc 负载均衡
    • grpc 身份认证
    • grpc 超时重试
    • grpc 链路追踪
    • grpc-gw将gRPC转RESTfu api
    • grpc-gw自定义选项
  • protobuf

    • protobuf 进阶
    • protobuf 编码原理
  • Docker

    • Docker基础
    • Docker常用命令
    • Dockerfile
    • Docker-Compose
    • Docker多阶段构建
    • Docker Config 教程
    • Docker Swarm 教程
    • Docker Stack 教程
    • Docker Buildx 教程
  • k8s

    • k8s 基础概念
    • k8s 集群架构
    • k8s 工作负载
    • Pod 网络
    • Service 网络
    • 外部接入网络
    • 一张图搞懂k8s各种pod
    • k8s 存储抽象
    • mac快速启动k8s
    • 自制申威架构k8s-reloader
  • go-kit

    • go-kit初识
    • go-kit启动http服务
    • go-kit集成gin启动服务
    • go-kit集成grpc和protobuf
    • go-kit中间件
    • go-kit服务注册发现与负载均衡
    • go-kit限流和熔断
    • go-kit链路追踪
    • go-kit集成Prometheus
  • 设计模式

    • 初识设计模式
    • 创建型模式
    • 结构型模式
    • 行为模式
  • 数据结构

    • 时间轮
    • 堆、双向链表、环形队列
    • 队列:优先队列
    • 队列:延迟队列
  • 算法

    • 递归算法
    • 枚举算法
    • 动态规划
    • 回溯算法
    • 分治算法
    • 贪心算法
    • LRU和LFU
    • 一致性哈希

花开半夏,半夏花开
首页
  • Go语言基础

    • 数据类型
    • 反射
    • Go指针
  • Go语言进阶

    • go泛型
    • go条件编译
    • cgo教程
    • Go协程调度原理及GPM模型
    • Go内存管理
    • Go垃圾回收机制
    • Go语言内存对齐
  • Go语言实现原理

    • channel 实现原理
    • slice 实现原理
    • map 实现原理
    • sync.Mutex 实现原理
    • 乐观锁CAS 实现原理
    • singlefight 实现原理
  • gin框架

    • gin中间件原理
    • gin路由原理
  • gorm

    • GORM介绍和使用
    • GORM_CURD操作指南
  • go测试

    • benchmark基准测试
    • pprof 性能分析
  • python进阶

    • Numpy&Pandas
    • celery分布式任务队列
  • Django

    • Django 常见命令
    • middleware中间件
    • Django缓存系统
    • Django信号系统
    • Django REST Framework
  • Flask

    • Flask基础知识总结
    • Flask-SQLAlchemy
  • 爬虫

    • aiohttp
    • scrapy框架
  • Mysql

    • Mysql存储引擎和索引
    • MySQL主从复制
    • Mysql读写分离
    • 数据库分库分表
    • Mysql锁
    • Mysql事务和MVCC原理
    • 分库分表带来的读扩散问题
  • Redis

    • redis基础和数据类型
    • redis主从架构
    • redis哨兵架构
    • redis集群模式
    • 如何保证缓存和数据库双写一致
    • redis底层数据结构
    • redis分布式锁
  • Elasticsearch

    • es基本概念
    • es基础语法
    • es倒排索引
  • etcd

    • Go操作etcd
    • Raft原理
    • etcd分布式锁
  • kafka

    • 消息队列MQ总结
    • kafka 概述及原理
    • kafka 消费问题记录
    • 零拷贝技术
    • kafka分区规范
  • RabbitMQ

    • rabbitMQ基础
    • Go操作rabbitmq
  • RocketMQ

    • 可靠消息队列 rocketMQ
  • Http&Https

    • http&https
    • TCP和UDP
    • Ping 原理
  • RPC

    • RPC初识
    • grpc初识和实现
  • gRPC

    • grpc 初识
    • grpc 上下文 metadata
    • grpc 健康检查
    • grpc keepalive
    • grpc 命名解析
    • grpc 中间件&拦截器
    • grpc 负载均衡
    • grpc 身份认证
    • grpc 超时重试
    • grpc 链路追踪
    • grpc-gw将gRPC转RESTfu api
    • grpc-gw自定义选项
  • protobuf

    • protobuf 进阶
    • protobuf 编码原理
  • Docker

    • Docker基础
    • Docker常用命令
    • Dockerfile
    • Docker-Compose
    • Docker多阶段构建
    • Docker Config 教程
    • Docker Swarm 教程
    • Docker Stack 教程
    • Docker Buildx 教程
  • k8s

    • k8s 基础概念
    • k8s 集群架构
    • k8s 工作负载
    • Pod 网络
    • Service 网络
    • 外部接入网络
    • 一张图搞懂k8s各种pod
    • k8s 存储抽象
    • mac快速启动k8s
    • 自制申威架构k8s-reloader
  • go-kit

    • go-kit初识
    • go-kit启动http服务
    • go-kit集成gin启动服务
    • go-kit集成grpc和protobuf
    • go-kit中间件
    • go-kit服务注册发现与负载均衡
    • go-kit限流和熔断
    • go-kit链路追踪
    • go-kit集成Prometheus
  • 设计模式

    • 初识设计模式
    • 创建型模式
    • 结构型模式
    • 行为模式
  • 数据结构

    • 时间轮
    • 堆、双向链表、环形队列
    • 队列:优先队列
    • 队列:延迟队列
  • 算法

    • 递归算法
    • 枚举算法
    • 动态规划
    • 回溯算法
    • 分治算法
    • 贪心算法
    • LRU和LFU
    • 一致性哈希
  • go语言基础

  • go语言进阶

    • go 泛型
    • go条件编译
    • 分布式从ACID、CAP、BASE的理论推进
    • go链接参数 ldflags
    • TCP网络连接以及TIME_WAIT的意义
    • Go异常处理
    • Go性能调优 pprof
    • Go语言设计模式
    • Go 切片的截取
    • Go runtime详解
    • go执行外部命令
      • 执行外部命令
        • 1. 方式一:run
        • 2. 方式二:start & wait
      • 输出日志
        • 1. 标准输出
        • 2. 转存文件
        • 3. 发送到网络
        • 4. 手动捕获
    • 标准库container三剑客:head、list、ring
    • go与http代理
    • Go内存管理
    • Go垃圾回收机制
    • Go语言中的并发编程
    • Go协程调度原理及GPM模型
    • Go中逃逸现象, 变量+堆栈
    • Go面向对象的思维理解interface
    • Go中的Defer
    • Go和Python中的深浅拷贝
    • Go语言内存对齐
    • 流和IO多路复用
    • 单点Server的N种并发模型汇总
    • 控制goroutine的数量
    • 配置管理库—Viper
    • 高性能日志库zap
    • Go中的Mutex和RWMutex.md
    • sqlx的使用
    • 分布式id 库snowflake和sonyflake
    • sync.Pool 复用对象
    • sync.Once 单例模式
    • sync.Cond 条件变量
    • unsafe.Pointer 和 uintptr
    • go 信号量
    • go语言代码优化技巧
    • go 接口型函数
    • 位运算
    • cgo教程
    • go调用lib和so动态库
  • go语言实现原理

  • gin框架

  • gorm

  • go测试

  • Go语言
  • go语言进阶
bigox
2023-02-27
目录

go执行外部命令

# 执行外部命令

# 1. 方式一:run

  • code

    func main() {
    	cmd := exec.Command("ls", "-l", "/var/log/")
    	err := cmd.Run()
    	if err != nil {
    		log.Fatalf("cmd.Run() failed with %s\n", err)
    	}
    }
    
    1
    2
    3
    4
    5
    6
    7
    • Run() 方法会启动命令并等待命令执行完毕。它会阻塞当前 goroutine 直到命令执行完毕,并返回一个 error 对象,该对象表示命令执行的错误信息。如果命令执行成功,Run() 方法会返回 nil
    • 直接调用 Cmd 对象的 Run 函数,返回的只有成功和失败,获取不到任何输出的结果

# 2. 方式二:start & wait

  • code

    func main() {
        // 使用 Start() 方法启动命令
        cmd = exec.Command("ping", "www.baidu.com")
        if err := cmd.Start(); err != nil {
            fmt.Println("Error:", err)
        }
        if err := cmd.Wait(); err != nil {
            fmt.Println("Error:", err)
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  • Start() 方法会启动命令并立即返回。它不会等待命令执行完毕,而是会在后台异步执行命令。Start() 方法返回一个 error 对象,该对象表示启动命令的错误信息。如果命令启动成功,Start() 方法会返回 nil

  • 在使用 Start() 方法启动命令后,我们可以使用 Wait() 方法等待命令执行完毕。Wait() 方法会阻塞当前 goroutine 直到命令执行完毕,并返回一个 error 对象,该对象表示命令执行的错误信息。如果命令执行成功,Wait() 方法会返回 nil

# 输出日志

https://darjun.github.io/2022/11/01/godailylib/osexec/

# 1. 标准输出

  • code

    func main() {
      cmd := exec.Command("cal")
      cmd.Stdout = os.Stdout
      cmd.Stderr = os.Stderr
      err := cmd.Run()
      if err != nil {
        log.Fatalf("cmd.Run() failed: %v\n", err)
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

# 2. 转存文件

  • code

    func main() {
      f, err := os.OpenFile("out.txt", os.O_WRONLY|os.O_CREATE, os.ModePerm)
      if err != nil {
        log.Fatalf("os.OpenFile() failed: %v\n", err)
      }
    
      cmd := exec.Command("cal")
      cmd.Stdout = f
      cmd.Stderr = f
      err = cmd.Run()
      if err != nil {
        log.Fatalf("cmd.Run() failed: %v\n", err)
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

# 3. 发送到网络

  • code

    func cal(w http.ResponseWriter, r *http.Request) {
      year := r.URL.Query().Get("year")
      month := r.URL.Query().Get("month")
    
      cmd := exec.Command("cal", month, year)
      cmd.Stdout = w
      cmd.Stderr = w
    
      err := cmd.Run()
      if err != nil {
        log.Fatalf("cmd.Run() failed: %v\n", err)
      }
    }
    
    func main() {
      http.HandleFunc("/cal", cal)
      http.ListenAndServe(":8080", nil)
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

# 4. 手动捕获

  • code

    package middleware
    
    import (
    	"bufio"
    	"fmt"
    	"git-biz.qianxin-inc.cn/upming/component/sdk-go-framework.git/log"
    	"io"
    	"os/exec"
    )
    
    type stdType int32
    
    const (
    	stdTypeStdout stdType = iota + 1
    	stdTypeStderr
    )
    
    func forkStdLog(cmd *exec.Cmd) error {
    	// 捕获标准输出
    	stdout, err := cmd.StdoutPipe()
    	if err != nil {
    		return fmt.Errorf("cmd.StdoutPipe() failed with %v", err)
    	}
    	go func() {
    		printExecStd(bufio.NewReader(stdout))
    	}()
    
    	// 捕获标准错误
    	stderr, err := cmd.StderrPipe()
    	if err != nil {
    		return fmt.Errorf("cmd.StderrPipe() failed with %v", err)
    	}
    	go func() {
    		// printExecStd(bufio.NewReader(stderr), stdTypeStderr)  // TODO 中间件s的输出不标准,后期再处理,需要加上这个参数
    		printExecStd(bufio.NewReader(stderr))
    	}()
    	return nil
    }
    
    func printExecStd(reader *bufio.Reader, std ...stdType) {
    	logger := log.WithField("[ middleware_s ]", "printExecStd")
    	var s stdType
    	if len(std) > 0 {
    		s = std[0]
    	} else {
    		s = stdTypeStdout
    	}
    	outputBytes := make([]byte, 1024)
    	for {
    		n, err := reader.Read(outputBytes) // 获取屏幕的实时输出(并不是按照回车分割)
    		if err != nil {
    			if err == io.EOF {
    				break
    			}
    			logger.Errorf("read %s failed with %v", std, err)
    		}
    		output := string(outputBytes[:n])
    		if s == stdTypeStdout {
    			logger.Info(output)
    		} else if s == stdTypeStderr {
    			logger.Error(output)
    		}
    	}
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
#Go
上次更新: 2023/08/27, 21:33:49
Go runtime详解
标准库container三剑客:head、list、ring

← Go runtime详解 标准库container三剑客:head、list、ring→

最近更新
01
go与http代理
05-24
02
自制申威架构k8s-reloader
12-06
03
Docker Buildx 教程
12-01
更多文章>
Theme by Vdoing | Copyright © 2020-2024 小刘扎扎 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式