171 lines
3.4 KiB
Go
171 lines
3.4 KiB
Go
package interceptor
|
||
|
||
import (
|
||
"bytes"
|
||
"errors"
|
||
"os/exec"
|
||
"runtime"
|
||
"strings"
|
||
)
|
||
|
||
// ShellModule 提供执行shell命令的功能
|
||
type ShellModule struct{}
|
||
|
||
// CommandResult 表示命令执行结果
|
||
type CommandResult struct {
|
||
Stdout string
|
||
Stderr string
|
||
ExitCode int
|
||
}
|
||
|
||
// Exec 执行shell命令并返回结果
|
||
func (s *ShellModule) Exec(command string) (*CommandResult, error) {
|
||
var cmd *exec.Cmd
|
||
var shell, flag string
|
||
|
||
switch runtime.GOOS {
|
||
case "windows":
|
||
shell = "cmd"
|
||
flag = "/c"
|
||
default: // linux, darwin, etc.
|
||
shell = "bash"
|
||
flag = "-c"
|
||
}
|
||
|
||
cmd = exec.Command(shell, flag, command)
|
||
|
||
var stdout, stderr bytes.Buffer
|
||
cmd.Stdout = &stdout
|
||
cmd.Stderr = &stderr
|
||
|
||
err := cmd.Run()
|
||
|
||
result := &CommandResult{
|
||
Stdout: stdout.String(),
|
||
Stderr: stderr.String(),
|
||
ExitCode: 0,
|
||
}
|
||
|
||
if err != nil {
|
||
if exitError, ok := err.(*exec.ExitError); ok {
|
||
result.ExitCode = exitError.ExitCode()
|
||
} else {
|
||
return result, err
|
||
}
|
||
}
|
||
|
||
return result, nil
|
||
}
|
||
|
||
// ExecPowerShell 在Windows上执行PowerShell命令
|
||
func (s *ShellModule) ExecPowerShell(command string) (*CommandResult, error) {
|
||
if runtime.GOOS != "windows" {
|
||
return nil, errors.New("PowerShell is only available on Windows")
|
||
}
|
||
|
||
cmd := exec.Command("powershell", "-Command", command)
|
||
|
||
var stdout, stderr bytes.Buffer
|
||
cmd.Stdout = &stdout
|
||
cmd.Stderr = &stderr
|
||
|
||
err := cmd.Run()
|
||
|
||
result := &CommandResult{
|
||
Stdout: stdout.String(),
|
||
Stderr: stderr.String(),
|
||
ExitCode: 0,
|
||
}
|
||
|
||
if err != nil {
|
||
if exitError, ok := err.(*exec.ExitError); ok {
|
||
result.ExitCode = exitError.ExitCode()
|
||
} else {
|
||
return result, err
|
||
}
|
||
}
|
||
|
||
return result, nil
|
||
}
|
||
|
||
// ExecBash 专门执行Bash命令(Linux/macOS)
|
||
func (s *ShellModule) ExecBash(command string) (*CommandResult, error) {
|
||
if runtime.GOOS == "windows" {
|
||
return nil, errors.New("Bash is not available on Windows by default")
|
||
}
|
||
|
||
cmd := exec.Command("bash", "-c", command)
|
||
|
||
var stdout, stderr bytes.Buffer
|
||
cmd.Stdout = &stdout
|
||
cmd.Stderr = &stderr
|
||
|
||
err := cmd.Run()
|
||
|
||
result := &CommandResult{
|
||
Stdout: stdout.String(),
|
||
Stderr: stderr.String(),
|
||
ExitCode: 0,
|
||
}
|
||
|
||
if err != nil {
|
||
if exitError, ok := err.(*exec.ExitError); ok {
|
||
result.ExitCode = exitError.ExitCode()
|
||
} else {
|
||
return result, err
|
||
}
|
||
}
|
||
|
||
return result, nil
|
||
}
|
||
|
||
// ExecCmd 专门执行Windows CMD命令
|
||
func (s *ShellModule) ExecCmd(command string) (*CommandResult, error) {
|
||
if runtime.GOOS != "windows" {
|
||
return nil, errors.New("CMD is only available on Windows")
|
||
}
|
||
|
||
cmd := exec.Command("cmd", "/c", command)
|
||
|
||
var stdout, stderr bytes.Buffer
|
||
cmd.Stdout = &stdout
|
||
cmd.Stderr = &stderr
|
||
|
||
err := cmd.Run()
|
||
|
||
result := &CommandResult{
|
||
Stdout: stdout.String(),
|
||
Stderr: stderr.String(),
|
||
ExitCode: 0,
|
||
}
|
||
|
||
if err != nil {
|
||
if exitError, ok := err.(*exec.ExitError); ok {
|
||
result.ExitCode = exitError.ExitCode()
|
||
} else {
|
||
return result, err
|
||
}
|
||
}
|
||
|
||
return result, nil
|
||
}
|
||
|
||
// ParseOutput 解析命令输出为字符串数组(按行分割)
|
||
func (s *ShellModule) ParseOutput(output string) []string {
|
||
return strings.Split(strings.TrimSpace(output), "\n")
|
||
}
|
||
|
||
// ParseKeyValue 解析键值对格式的输出(如 KEY=VALUE)
|
||
func (s *ShellModule) ParseKeyValue(output string) map[string]string {
|
||
result := make(map[string]string)
|
||
lines := s.ParseOutput(output)
|
||
|
||
for _, line := range lines {
|
||
parts := strings.SplitN(line, "=", 2)
|
||
if len(parts) == 2 {
|
||
result[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
|
||
}
|
||
}
|
||
|
||
return result
|
||
} |