Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute system command with unknown arguments?

Tags:

go

I have a bunch of systems commands which are somwhat similar to appending new content to a file. I wrote a simple script to execute system commands, which works well if there are single words like 'ls' , 'date' etc. But if the command is greater than that, program dies.

The following is the code

package main  import (     "fmt"     "os/exec"     "sync" )  func exe_cmd(cmd string, wg *sync.WaitGroup) {     fmt.Println(cmd)     c = cmd.Str     out, err := exec.Command(cmd).Output()     if err != nil {         fmt.Println("error occured")         fmt.Printf("%s", err)     }     fmt.Printf("%s", out)     wg.Done() }  func main() {     wg := new(sync.WaitGroup)     wg.Add(3)      x := []string{"echo newline >> foo.o", "echo newline >> f1.o", "echo newline >> f2.o"}     go exe_cmd(x[0], wg)     go exe_cmd(x[1], wg)     go exe_cmd(x[2], wg)      wg.Wait() } 

The following is the error i see

exec: "echo newline >> foo.o": executable file not found in $PATHexec:  "echo newline >> f2.o": executable file not found in $PATHexec:  "echo newline >> f1.o": executable file not found in $PATH  

I guess, this may be due to, not sending cmds and arguments seperately ( http://golang.org/pkg/os/exec/#Command ). I am wondering how to subvert this, since I don't know how many arguments will be there in my command which needs to be executed.

like image 320
Rahul Avatar asked Dec 07 '13 03:12

Rahul


1 Answers

I found a relatively decent way to achieve the same .

out, err := exec.Command("sh","-c",cmd).Output() 

Works for me until now. Still finding better ways to achieve the same.

Edit1:

Finally a easier and efficient (atleast so far) way to do would be like this

func exeCmd(cmd string, wg *sync.WaitGroup) {   fmt.Println("command is ",cmd)   // splitting head => g++ parts => rest of the command   parts := strings.Fields(cmd)   head := parts[0]   parts = parts[1:len(parts)]    out, err := exec.Command(head,parts...).Output()   if err != nil {     fmt.Printf("%s", err)   }   fmt.Printf("%s", out)   wg.Done() // Need to signal to waitgroup that this goroutine is done } 

Thanks to variadic arguments in go and people that pointed that out to me :)

like image 103
Rahul Avatar answered Sep 26 '22 09:09

Rahul