add executable check for commands

This commit is contained in:
Shane C 2024-07-04 17:14:10 -04:00
parent 3a9d03a46f
commit c10fdf32b2
Signed by: shane
GPG key ID: E46B5FEA35B22FF9
5 changed files with 59 additions and 5 deletions

View file

@ -19,7 +19,8 @@ type CommandOptions struct {
// Errors // Errors
var ( var (
ErrFetchingCwd = errors.New("error fetching cwd") ErrFetchingCwd = errors.New("error fetching cwd")
ErrRunningCmd = errors.New("error running command") ErrRunningCmd = errors.New("error running command")
ErrCommandNotFound = errors.New("error command not found") ErrCommandNotFound = errors.New("error command not found")
ErrCommandNotExecutable = errors.New("error command not executable")
) )

View file

@ -30,6 +30,7 @@ func NewCommand(options CommandOptions) (*LinuxCommand, error) {
func (cmd *LinuxCommand) Run() error { func (cmd *LinuxCommand) Run() error {
command := exec.Command(cmd.Options.Shell, "-c", cmd.Options.Command) command := exec.Command(cmd.Options.Shell, "-c", cmd.Options.Command)
command.Path = cmd.Options.Cwd
command.Args = append(command.Args, cmd.Options.Args...) command.Args = append(command.Args, cmd.Options.Args...)
// Loop through env to format and add them to the command. // Loop through env to format and add them to the command.
@ -37,6 +38,15 @@ func (cmd *LinuxCommand) Run() error {
command.Env = append(command.Env, fmt.Sprintf("%s=%s", key, value)) command.Env = append(command.Env, fmt.Sprintf("%s=%s", key, value))
} }
isCommandExecutable, err := cmd.isCommandExecutable(cmd.Options.Command)
if err != nil {
return err
}
if !isCommandExecutable {
return ErrCommandNotExecutable
}
if err := command.Start(); err != nil { if err := command.Start(); err != nil {
var exitErr *exec.ExitError var exitErr *exec.ExitError
if errors.As(err, &exitErr) { if errors.As(err, &exitErr) {
@ -49,7 +59,7 @@ func (cmd *LinuxCommand) Run() error {
} }
} }
if err := command.Start(); err != nil { if err := command.Wait(); err != nil {
var exitErr *exec.ExitError var exitErr *exec.ExitError
if errors.As(err, &exitErr) { if errors.As(err, &exitErr) {
fmt.Println(exitErr.ExitCode()) fmt.Println(exitErr.ExitCode())

View file

@ -3,9 +3,30 @@ package linux
import ( import (
"errors" "errors"
"fmt" "fmt"
"golang.org/x/sys/unix"
"io/fs"
"os"
"os/exec" "os/exec"
) )
func (cmd *LinuxCommand) isCommandExecutable(command string) (bool, error) {
if _, err := os.Stat(command); errors.Is(err, fs.ErrNotExist) {
return false, err
}
if err := unix.Access(command, unix.X_OK); err != nil {
if !errors.Is(err, unix.EACCES) {
return false, nil
} else {
return false, err
}
}
return true, nil
}
func (cmd *LinuxCommand) doesCommandExist(command string) (bool, error) { func (cmd *LinuxCommand) doesCommandExist(command string) (bool, error) {
shellCmd := exec.Command(cmd.Options.Shell, "-c", fmt.Sprintf("command -v %s", command)) shellCmd := exec.Command(cmd.Options.Shell, "-c", fmt.Sprintf("command -v %s", command))

View file

@ -1,4 +1,4 @@
package shell package main
import ( import (
"bytes" "bytes"

22
test.go Normal file
View file

@ -0,0 +1,22 @@
package main
import (
"git.shadowhosting.xyz/Eggactyl/shell/linux"
"log"
)
func main() {
cmd, err := linux.NewCommand(linux.CommandOptions{
Command: "./test.sh",
})
if err != nil {
log.Fatalln(err)
}
if err := cmd.Run(); err != nil {
log.Fatalln(err)
}
}