package cmd
import (
"bytes"
"io"
"os"
"os/exec"
"strings"
"sync"
)
var (
sudoHandleCmd string
sudoCheckOnce sync.Once
)
func CheckIllegal(args ...string) bool {
if args == nil {
return false
}
for _, arg := range args {
if strings.Contains(arg, "&") || strings.Contains(arg, "|") || strings.Contains(arg, ";") ||
strings.Contains(arg, "$") || strings.Contains(arg, "'") || strings.Contains(arg, "`") ||
strings.Contains(arg, "(") || strings.Contains(arg, ")") || strings.Contains(arg, "\"") ||
strings.Contains(arg, "\n") || strings.Contains(arg, "\r") || strings.Contains(arg, ">") || strings.Contains(arg, "<") {
return true
}
}
return false
}
func SudoHandleCmd() string {
sudoCheckOnce.Do(func() {
cmd := exec.Command("sudo", "-n", "ls")
if err := cmd.Run(); err == nil {
sudoHandleCmd = "sudo "
}
})
return sudoHandleCmd
}
func WrapWithOptionalSudo(name string, args ...string) (string, []string) {
if SudoHandleCmd() == "" {
return name, args
}
return "sudo", append([]string{"-n", name}, args...)
}
func ExecCommandWithOptionalSudo(name string, args ...string) *exec.Cmd {
commandName, commandArgs := WrapWithOptionalSudo(name, args...)
return exec.Command(commandName, commandArgs...)
}
func WriteFileWithOptionalSudo(name string, data []byte, perm os.FileMode) error {
if err := os.WriteFile(name, data, perm); err == nil {
return nil
} else if SudoHandleCmd() == "" {
return err
}
command := exec.Command("sudo", "-n", "tee", name)
command.Stdin = bytes.NewReader(data)
command.Stdout = io.Discard
return command.Run()
}
func Which(name string) bool {
_, err := exec.LookPath(name)
return err == nil
}