tolo/executor/executor.go

60 lines
1.1 KiB
Go
Raw Permalink Normal View History

package executor
import (
"fmt"
"os"
"os/exec"
"strings"
"syscall"
)
func Execute(command string) error {
parts := parseCommand(command)
if len(parts) == 0 {
return fmt.Errorf("empty command")
}
cmd := exec.Command(parts[0], parts[1:]...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
os.Exit(status.ExitStatus())
}
}
return fmt.Errorf("command failed: %w", err)
}
return nil
}
func parseCommand(command string) []string {
var parts []string
var current strings.Builder
var inSingleQuote, inDoubleQuote bool
for _, r := range command {
switch {
case r == '\'' && !inDoubleQuote:
inSingleQuote = !inSingleQuote
case r == '"' && !inSingleQuote:
inDoubleQuote = !inDoubleQuote
case r == ' ' && !inSingleQuote && !inDoubleQuote:
if current.Len() > 0 {
parts = append(parts, current.String())
current.Reset()
}
default:
current.WriteRune(r)
}
}
if current.Len() > 0 {
parts = append(parts, current.String())
}
return parts
}