gosh/interceptor/shell.go

171 lines
3.4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}