首页 > 系统相关 >golang shell

golang shell

时间:2024-09-28 16:22:36浏览次数:9  
标签:shell struct chan golang customOutput string

package shell

import (
	"context"
	"fmt"
	"os/exec"
	"time"
)

// 自定义输出结构体
type customOutput struct {
	outPut   chan string
	resetCtx chan struct{}
}

// Write 将输出写入到 customOutput 结构体中,并通知重置超时。
func (c customOutput) Write(p []byte) (int, error) {
	output := string(p)
	c.outPut <- output
	c.resetCtx <- struct{}{} // 每次有输出时通知续期
	return len(p), nil
}

type CustomShellCommand struct {
	cmd      *exec.Cmd
	outPipe  chan string
	resetCtx chan struct{}
	ctx      context.Context
	cancel   context.CancelFunc
	timer    *time.Timer
	timeout  time.Duration
}

// NewShell 创建新的 Shell 命令实例
func NewShell(command []string, timeout time.Duration) *CustomShellCommand {
	ctx, cancel := context.WithCancel(context.Background())
	outPipe := make(chan string, 100)
	resetCtx := make(chan struct{}, 1) // 用于通知续期

	cmd := exec.CommandContext(ctx, command[0], command[1:]...)
	cmd.Stdout = customOutput{outPipe, resetCtx}

	// 创建并返回 CustomShellCommand
	return &CustomShellCommand{
		cmd:      cmd,
		outPipe:  outPipe,
		resetCtx: resetCtx,
		ctx:      ctx,
		timeout:  timeout,
		cancel:   cancel,
		timer:    time.NewTimer(timeout), // 设置初始超时
	}
}

// Run 执行命令并处理续期超时
func (c *CustomShellCommand) Run() error {
	errChan := make(chan error, 1) // 创建一个缓冲区大小为1的错误通道

	go func() {
		err := c.cmd.Run() // 在 goroutine 中执行命令
		//if err != nil {
		//	fmt.Println("Command exited with error:", err)
		//}
		errChan <- err // 将错误发送到错误通道
		c.cancel()     // 当命令执行完成时取消上下文
	}()

	for {
		select {
		case <-c.ctx.Done(): // 当命令被取消或完成时退出
			//fmt.Println("Command context done.")
			return c.ctx.Err()
		case <-c.timer.C: // 当超时没有输出时,停止命令
			//fmt.Println("Command timed out.")
			c.cancel()
			return fmt.Errorf("command timed out")
		case <-c.resetCtx: // 当有输出时重置超时计时器
			if !c.timer.Stop() {
				<-c.timer.C // 确保通道被清空
			}
			c.timer.Reset(c.timeout) // 重置计时器为
		case err := <-errChan: // 捕获命令执行的错误
			return err // 返回错误
		}
	}
}

// Killed 取消任务
func (c *CustomShellCommand) Killed() {
	c.cancel()
}

// GetOutputPipe 返回命令的输出通道
func (c *CustomShellCommand) GetOutputPipe() <-chan string {
	return c.outPipe
}

// Close 关闭输出通道并取消上下文
func (c *CustomShellCommand) Close() {
	close(c.outPipe)
	c.cancel()
}

  

标签:shell,struct,chan,golang,customOutput,string
From: https://www.cnblogs.com/hoganhome/p/18438107

相关文章

  • rust运行shell命令并获取输出
    usestd::io::{BufReader,BufRead};usestd::process::{self,Command,Stdio};fnmain(){ls();ps();xargs();time();iostat();}//不带参数命令fnls(){letoutput=Command::new("ls").output().expect("执行异常,提示");......
  • PowerShell 脚本禁用 Realtek Audio Console 中的前面板插孔检测,通常需要修改注册表项
     PowerShell脚本禁用RealtekAudioConsole中的前面板插孔检测,通常需要修改注册表项。以下是一个示例脚本,用于执行此操作:powershellCopyCode#设置注册表路径$registryPath="HKLM:\SOFTWARE\Realtek\Audio\RtkNGUI\Settings"#检查注册表路径是否存在if(-not(Test-......
  • shell基础知识
    shell基础知识前言Shell是一个应用程序,它连接了用户和Linux内核,让用户能够更加高效、安全、低成本地使用Linux内核,这就是Shell的本质。然而Shell本身并不是内核的一部分,它只是站在内核的基础上编写的一个应用程序,但是Shell也有着它的特殊性,就是开机立马启动,并呈现在......
  • shell中set指令的用法
    语法set[-可选参数][-o选项]功能说明set指令可根据不同的需求来设置当前所使用shell的执行方式,同时也可以用来设置或显示shell变量的值。当指定某个单一的选项时将设置shell的常用特性,如果在选项后使用-o参数将打开特殊特性,若是+o将关闭相应的特殊特性。而不带任......
  • 易优CMS致命错误,联系技术支持:Call to undefined function eyPreventShell()-eyoucms
    当你遇到 core/helper.php 第146行左右出现致命错误,并且提示 CalltoundefinedfunctioneyPreventShell() 时,通常是因为某个自定义函数未被定义或未被正确引入。以下是一些具体的解决步骤:步骤1:检查函数定义定位 eyPreventShell 函数查找 eyPreventShell 函数的......
  • 【Golang】双节点集群etcd未组成集群vip切换时序
    目录1、背景2、时序图1、背景在vip(虚拟ip)可以从一个节点切换到另一个节点,但etcd未组成集群的环境中,与etcd的连接会断开重连,但同一个key在不同节点的版本可能会不一样导致etcd服务器不向客户端推送数据,也就是客户端watch失效了,具体解决方法参考之前的重连方法。下面......
  • export PATH="/opt/homebrew/bin:$PATH" 或者eval "$(/opt/homebrew/bin/brew shellen
    这两种方式都是为了将Homebrew的路径添加到系统的环境变量PATH中,使得可以在终端中使用Homebrew命令,但它们的实现方式和作用略有不同。exportPATH="/opt/homebrew/bin:$PATH":这种方式是直接将Homebrew的安装路径(/opt/homebrew/bin)添加到当前shell会话的PATH变量......
  • CShell.dll错误怎么办?CShell.dll文件错误解析:从根源到解决方案的全面指导
    一、CShell.dll文件概述CShell.dll是电脑系统中的一个动态链接库文件(DynamicLinkLibrary,DLL),它包含了程序运行所需的代码和数据。当系统或某个软件需要调用这些代码时,就会加载CShell.dll文件。然而,有时由于各种原因,CShell.dll文件可能会出现错误,导致程序无法正常运行。二......
  • golang性能测试框架k6源码分析
    Golang性能测试框架k6是一个新兴的性能测试工具,其特点在于使用JavaScript作为测试脚本语言,并且基于Golang的强大性能进行构建。1.框架基础k6的启动框架使用了Golang的CLI标准框架cobra。cobra是一个用于构建CLI应用程序的库,它提供了丰富的命令解析和参数处理功能。在k6中,getRunCm......
  • Goland golang 源码阅读环境搭建
    本环境是基于阿里云os搭建的,其实可用centos代替1安装工具包  sudoyuminstallgcc git2安装go环境  yuminstallgolang2首先从github下载源码  gitclone GitHub-golang/go:TheGoprogramminglanguage3执行编译  进行go目录下面的src目录,......