From e159cf5b1ce94be9f1d81399ea90a854d9f15e0a Mon Sep 17 00:00:00 2001 From: zyj Date: Mon, 14 Jul 2025 00:13:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=BF=9B=E7=A8=8B=E5=AE=88?= =?UTF-8?q?=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 82 +++++++++++++++++++++++++++++++++++++++++++ main.txt | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 main.txt diff --git a/main.go b/main.go index 4e4259a..282ff26 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,16 @@ package main import ( + "bufio" + "context" "flag" "fmt" + "io" "os" + "os/exec" + "os/signal" + "sync" + "syscall" ) var ( @@ -34,4 +41,79 @@ func main() { if *stop != "" { fmt.Println("停止:", *stop) } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + cmd := exec.CommandContext(ctx, "go", "run", "src\\index.go") + cmd.Dir = "D:\\project\\Go\\src\\go-fingerprint\\" + // if err := cmd.Start(); err != nil { + // fmt.Println("运行报错") + // } + // 创建管道捕获标准输出 + stdout, err := cmd.StdoutPipe() + if err != nil { + fmt.Errorf("创建标准输出管道失败: %v", err) + } + + // 创建管道捕获标准错误 + stderr, err := cmd.StderrPipe() + if err != nil { + fmt.Errorf("创建标准错误管道失败: %v", err) + } + + // 启动命令 + if err := cmd.Start(); err != nil { + fmt.Errorf("启动命令失败: %v", err) + } + // 使用 WaitGroup 等待输出处理完成 + var wg sync.WaitGroup + wg.Add(2) + + // 处理标准输出 + go func() { + defer wg.Done() + scanAndCapture(stdout, "STDOUT") + }() + + // 处理标准错误 + go func() { + defer wg.Done() + scanAndCapture(stderr, "STDERR") + }() + // 等待命令执行完成 + if err := cmd.Wait(); err != nil { + fmt.Errorf("命令执行失败: %v", err) + } + setupSignalHandler() + // 等待所有输出处理完成 + wg.Wait() + cmd.Wait() +} + +// 扫描并捕获输出 +func scanAndCapture(reader io.Reader, prefix string) { + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + line := scanner.Text() + var outputLines []string + // 捕获输出行(最多保留1000行) + outputLines = append(outputLines, line) + if len(outputLines) > 1000 { + outputLines = outputLines[1:] + } + + // 实时显示 + fmt.Printf("[%s] %s\n", prefix, line) + } +} + +func setupSignalHandler() { + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) + + go func() { + <-sigChan + fmt.Println("\n接收到中断信号,停止子进程...") + os.Exit(0) + }() } diff --git a/main.txt b/main.txt new file mode 100644 index 0000000..25365da --- /dev/null +++ b/main.txt @@ -0,0 +1,104 @@ +package main + +import ( + "bufio" + "context" + "fmt" + "io" + "os" + "os/exec" + "os/signal" + "sync" + "syscall" +) + +func main() { + // 1. 创建上下文用于任务控制 + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // 2. 设置信号处理(Ctrl+C) + setupSignalHandler(cancel) + + // 3. 创建并配置命令 + cmd := createCommand(ctx, "go", "run", "src\\index.go") + cmd.Dir = "D:\\project\\Go\\src\\go-fingerprint\\" + // 4. 获取输出管道 + stdout := getOutputPipe(cmd, "stdout") + stderr := getOutputPipe(cmd, "stderr") + + // 5. 启动任务 + if err := cmd.Start(); err != nil { + fmt.Printf("启动失败: %v\n", err) + return + } + fmt.Printf("任务已启动 (PID: %d)\n", cmd.Process.Pid) + + // 6. 启动输出处理协程 + var wg sync.WaitGroup + wg.Add(2) + go processOutput(&wg, stdout, "OUT") + go processOutput(&wg, stderr, "ERR") + + // 7. 等待任务完成 + if err := cmd.Wait(); err != nil { + fmt.Printf("任务结束: %v\n", err) + } + + // 8. 等待所有输出处理完成 + wg.Wait() + fmt.Println("程序退出") +} + +// 创建可执行命令 +func createCommand(ctx context.Context, command string, args ...string) *exec.Cmd { + cmd := exec.CommandContext(ctx, command, args...) + cmd.Dir = "." // 设置工作目录 + return cmd +} + +// 获取输出管道 +func getOutputPipe(cmd *exec.Cmd, stream string) io.Reader { + var pipe io.Reader + var err error + + switch stream { + case "stdout": + pipe, err = cmd.StdoutPipe() + case "stderr": + pipe, err = cmd.StderrPipe() + } + + if err != nil { + fmt.Printf("创建%s管道失败: %v\n", stream, err) + return nil + } + return pipe +} + +// 处理任务输出 +func processOutput(wg *sync.WaitGroup, reader io.Reader, prefix string) { + defer wg.Done() + + if reader == nil { + return + } + + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + fmt.Printf("[%s] %s\n", prefix, scanner.Text()) + } +} + +// 设置信号处理 +func setupSignalHandler(cancel context.CancelFunc) { + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) + + go func() { + <-sigChan + fmt.Println("\n收到停止信号,停止任务...") + cancel() + }() +} +