While in general you need goroutines to run something parallel (or, rather, parallel), in the case of running an external command or application in this way you do not need to use goroutines (in fact, it is redundant).
This is because the one exec.Cmdused to run the commands has Cmd.Start()one that launches the specified command, but without waiting for its completion. That way, you can do other things while they are running in the background, and when you need to wait for completion (and process its result), you can call Cmd.Wait()(which blocks and waits for the command to complete).
Here's what it might look like:
cmd := exec.Command("npm", "install", "other_params")
cmd.Dir = entryPath
if err := cmd.Start(); err != nil {
log.Printf("Failed to start cmd: %v", err)
return
}
log.Println("Doing other stuff...")
if err := cmd.Wait(); err != nil {
log.Printf("Cmd returned error: %v", err)
}
Cmd.Start() Cmd.Run(), , " ". Cmd.Run() , Cmd.Start() Cmd.Wait().
, Cmd.Output() Cmd.CombinedOutput(), ( ). , Cmd.Stdout, / .
:
cmd := exec.Command("npm", "install", "other_params")
cmd.Dir = entryPath
buf := &bytes.Buffer{}
cmd.Stdout = buf
if err := cmd.Start(); err != nil {
log.Printf("Failed to start cmd: %v", err)
return
}
// Do other stuff while cmd runs in background:
log.Println("Doing other stuff...")
// And when you need to wait for the command to finish:
if err := cmd.Wait(); err != nil {
log.Printf("Cmd returned error: %v", err)
// You may decide to continue or return here...
}
fmt.Println("[OUTPUT:]", buf.String())
, / Cmd.Stderr. . Cmd.Stdout Cmd.Stderr, , :
Stdout Stderr , ==,
goroutine Write.