修改进程守护
This commit is contained in:
82
main.go
82
main.go
@@ -1,9 +1,16 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"os/signal"
|
||||||
|
"sync"
|
||||||
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -34,4 +41,79 @@ func main() {
|
|||||||
if *stop != "" {
|
if *stop != "" {
|
||||||
fmt.Println("停止:", *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)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|||||||
104
main.txt
Normal file
104
main.txt
Normal file
@@ -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()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user