Skip to content

Commit

Permalink
fix: 优化命令参数格式化
Browse files Browse the repository at this point in the history
  • Loading branch information
devhaozi committed Feb 12, 2025
1 parent f0a9ace commit a91d0b7
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 17 deletions.
2 changes: 1 addition & 1 deletion internal/service/ws.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (s *WsService) Exec(w http.ResponseWriter, r *http.Request) {
}

ctx, cancel := context.WithCancel(context.Background())
out, err := shell.ExecfWithPipe(ctx, string(cmd)) // nolint: govet
out, err := shell.ExecfWithPipe(ctx, string(cmd))
if err != nil {
_ = ws.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "failed to run command"))
cancel()
Expand Down
53 changes: 37 additions & 16 deletions pkg/shell/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,19 @@ func Execf(shell string, args ...any) (string, error) {
if !preCheckArg(args) {
return "", errors.New("command contains illegal characters")
}
if len(args) > 0 {
shell = fmt.Sprintf(shell, args...)
}

_ = os.Setenv("LC_ALL", "C")
cmd := exec.Command("bash", "-c", fmt.Sprintf(shell, args...))
cmd := exec.Command("bash", "-c", shell)

var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr

if err := cmd.Run(); err != nil {
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", fmt.Sprintf(shell, args...), strings.TrimSpace(stderr.String()))
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", shell, strings.TrimSpace(stderr.String()))
}

return strings.TrimSpace(stdout.String()), nil
Expand All @@ -57,9 +60,12 @@ func ExecfAsync(shell string, args ...any) error {
if !preCheckArg(args) {
return errors.New("command contains illegal characters")
}
if len(args) > 0 {
shell = fmt.Sprintf(shell, args...)
}

_ = os.Setenv("LC_ALL", "C")
cmd := exec.Command("bash", "-c", fmt.Sprintf(shell, args...))
cmd := exec.Command("bash", "-c", shell)

err := cmd.Start()
if err != nil {
Expand All @@ -68,7 +74,7 @@ func ExecfAsync(shell string, args ...any) error {

go func() {
if err = cmd.Wait(); err != nil {
fmt.Println(fmt.Errorf("run %s failed, err: %s", fmt.Sprintf(shell, args...), strings.TrimSpace(err.Error())))
fmt.Println(fmt.Errorf("run %s failed, err: %s", shell, strings.TrimSpace(err.Error())))
}
}()

Expand All @@ -80,17 +86,20 @@ func ExecfWithTimeout(timeout time.Duration, shell string, args ...any) (string,
if !preCheckArg(args) {
return "", errors.New("command contains illegal characters")
}
if len(args) > 0 {
shell = fmt.Sprintf(shell, args...)
}

_ = os.Setenv("LC_ALL", "C")
cmd := exec.Command("bash", "-c", fmt.Sprintf(shell, args...))
cmd := exec.Command("bash", "-c", shell)

var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr

err := cmd.Start()
if err != nil {
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", fmt.Sprintf(shell, args...), strings.TrimSpace(stderr.String()))
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", shell, strings.TrimSpace(stderr.String()))
}

done := make(chan error)
Expand All @@ -101,10 +110,10 @@ func ExecfWithTimeout(timeout time.Duration, shell string, args ...any) (string,
select {
case <-time.After(timeout):
_ = cmd.Process.Kill()
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", fmt.Sprintf(shell, args...), "timeout")
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", shell, "timeout")
case err = <-done:
if err != nil {
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", fmt.Sprintf(shell, args...), strings.TrimSpace(stderr.String()))
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", shell, strings.TrimSpace(stderr.String()))
}
}

Expand All @@ -116,9 +125,12 @@ func ExecfWithOutput(shell string, args ...any) error {
if !preCheckArg(args) {
return errors.New("command contains illegal characters")
}
if len(args) > 0 {
shell = fmt.Sprintf(shell, args...)
}

_ = os.Setenv("LC_ALL", "C")
cmd := exec.Command("bash", "-c", fmt.Sprintf(shell, args...))
cmd := exec.Command("bash", "-c", shell)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

Expand All @@ -130,9 +142,12 @@ func ExecfWithPipe(ctx context.Context, shell string, args ...any) (out io.ReadC
if !preCheckArg(args) {
return nil, errors.New("command contains illegal characters")
}
if len(args) > 0 {
shell = fmt.Sprintf(shell, args...)
}

_ = os.Setenv("LC_ALL", "C")
cmd := exec.CommandContext(ctx, "bash", "-c", fmt.Sprintf(shell, args...))
cmd := exec.CommandContext(ctx, "bash", "-c", shell)

out, err = cmd.StdoutPipe()
if err != nil {
Expand All @@ -149,17 +164,20 @@ func ExecfWithDir(dir, shell string, args ...any) (string, error) {
if !preCheckArg(args) {
return "", errors.New("command contains illegal characters")
}
if len(args) > 0 {
shell = fmt.Sprintf(shell, args...)
}

_ = os.Setenv("LC_ALL", "C")
cmd := exec.Command("bash", "-c", fmt.Sprintf(shell, args...))
cmd := exec.Command("bash", "-c", shell)
cmd.Dir = dir

var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr

if err := cmd.Run(); err != nil {
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", fmt.Sprintf(shell, args...), strings.TrimSpace(stderr.String()))
return strings.TrimSpace(stdout.String()), fmt.Errorf("run %s failed, err: %s", shell, strings.TrimSpace(stderr.String()))
}

return strings.TrimSpace(stdout.String()), nil
Expand All @@ -170,25 +188,28 @@ func ExecfWithTTY(shell string, args ...any) (string, error) {
if !preCheckArg(args) {
return "", errors.New("command contains illegal characters")
}
if len(args) > 0 {
shell = fmt.Sprintf(shell, args...)
}

_ = os.Setenv("LC_ALL", "C")
cmd := exec.Command("bash", "-i", "-c", fmt.Sprintf(shell, args...))
cmd := exec.Command("bash", "-i", "-c", shell)

var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stderr = &stderr // https://github.com/creack/pty/issues/147 取 stderr

f, err := pty.Start(cmd)
if err != nil {
return "", fmt.Errorf("run %s failed", fmt.Sprintf(shell, args...))
return "", fmt.Errorf("run %s failed", shell)
}
defer f.Close()

if _, err = io.Copy(&out, f); ptyError(err) != nil {
return "", fmt.Errorf("run %s failed, out: %s, err: %w", fmt.Sprintf(shell, args...), strings.TrimSpace(out.String()), err)
return "", fmt.Errorf("run %s failed, out: %s, err: %w", shell, strings.TrimSpace(out.String()), err)
}
if stderr.Len() > 0 {
return "", fmt.Errorf("run %s failed, out: %s", fmt.Sprintf(shell, args...), strings.TrimSpace(stderr.String()))
return "", fmt.Errorf("run %s failed, out: %s", shell, strings.TrimSpace(stderr.String()))
}

return strings.TrimSpace(out.String()), nil
Expand Down

0 comments on commit a91d0b7

Please sign in to comment.