Метод exec.Cmd.Start
Метод exec.Cmd.Start запускает внешний процесс, используя параметры, заданные в структуре exec.Cmd. В отличие от метода Run, который запускает процесс и ожидает его завершения, метод Start возвращает управление сразу после запуска процесса. Метод возвращает ошибку, если процесс не удалось запустить. После вызова Start необходимо вызвать метод Wait, чтобы дождаться завершения процесса и освободить системные ресурсы.
Синтаксис
cmd := exec.Command(name, arg...)
err := cmd.Start()
Пример
Давайте запустим команду echo в асинхронном режиме и дождемся ее завершения с помощью метода Wait:
package main
import (
"exec"
"fmt"
"log"
)
func main() {
cmd := exec.Command("echo", "Hello, World!")
err := cmd.Start()
if err != nil {
log.Fatal(err)
}
fmt.Println("Process started")
err = cmd.Wait()
if err != nil {
log.Fatal(err)
}
fmt.Println("Process finished")
}
Результат выполнения кода:
"Process started"
"Hello, World!"
"Process finished"
Пример
Давайте запустим длительный процесс и проверим, что управление возвращается немедленно, а процесс продолжает выполняться в фоне:
package main
import (
"exec"
"fmt"
"log"
"time"
)
func main() {
cmd := exec.Command("sleep", "3")
err := cmd.Start()
if err != nil {
log.Fatal(err)
}
fmt.Println("Command started at", time.Now().Format("15:04:05"))
err = cmd.Wait()
if err != nil {
log.Fatal(err)
}
fmt.Println("Command finished at", time.Now().Format("15:04:05"))
}
Результат выполнения кода:
"Command started at 14:30:15"
"Command finished at 14:30:18"
Как видно из примера, между запуском и завершением процесса прошло примерно 3 секунды, но сообщение о запуске вывелось сразу, без ожидания завершения команды.
Пример
Давайте запустим процесс с перенаправлением стандартного вывода в буфер и прочитаем результат после завершения:
package main
import (
"bytes"
"exec"
"fmt"
"log"
)
func main() {
var stdout bytes.Buffer
cmd := exec.Command("ls", "-l")
cmd.Stdout = &stdout
err := cmd.Start()
if err != nil {
log.Fatal(err)
}
err = cmd.Wait()
if err != nil {
log.Fatal(err)
}
fmt.Println(stdout.String())
}
Результат выполнения кода:
"total 0\n-rw-r--r-- 1 user user 0 Jan 1 00:00 file1.txt\n-rw-r--r-- 1 user user 0 Jan 1 00:00 file2.txt\n"
Пример
Давайте обработаем ошибку, которая возникает при попытке запустить несуществующую команду:
package main
import (
"exec"
"fmt"
"log"
)
func main() {
cmd := exec.Command("nonexistent-command")
err := cmd.Start()
if err != nil {
fmt.Println("Error:", err)
return
}
err = cmd.Wait()
if err != nil {
log.Fatal(err)
}
}
Результат выполнения кода:
"Error: exec: \"nonexistent-command\": executable file not found in $PATH"
Важно отметить, что метод Start возвращает ошибку только в случае проблем с запуском процесса. Если процесс запустился, но завершился с ненулевым кодом возврата, ошибку вернет метод Wait, а не Start.
Смотрите также
-
метод
exec.Cmd.Run,
который запускает процесс и ожидает его завершения -
метод
exec.Cmd.Wait,
который ожидает завершения процесса и освобождает ресурсы -
функцию
exec.Command,
которая создает структуруCmdдля выполнения внешней команды -
метод
exec.Cmd.Output,
который выполняет команду и возвращает стандартный вывод