Go на примерах: Exec процессов

В предыдущем примере мы рассмотрели порождение внешних процессов. Мы делаем это, когда нужен внешний процесс, доступный работающему процессу Go. Иногда мы просто хотим полностью заменить текущий процесс Go другим (возможно, не Go) процессом. Для этого используем реализацию Go классической функции exec.

package main
import (
    "os"
    "os/exec"
    "syscall"
)
func main() {

Для нашего примера выполним exec для ls. Go требует абсолютный путь к бинарному файлу, который хотим выполнить, поэтому используем exec.LookPath для его поиска (вероятно, /bin/ls).

    binary, lookErr := exec.LookPath("ls")
    if lookErr != nil {
        panic(lookErr)
    }

Exec требует аргументы в виде среза (в отличие от одной большой строки). Дадим ls несколько распространённых аргументов. Обрати внимание, что первым аргументом должно быть имя программы.

    args := []string{"ls", "-a", "-l", "-h"}

Exec также нужен набор переменных окружения для использования. Здесь мы просто передаём наше текущее окружение.

    env := os.Environ()

Вот фактический вызов syscall.Exec. Если этот вызов успешен, выполнение нашего процесса закончится здесь и будет заменено процессом /bin/ls -a -l -h. Если есть ошибка, получим возвращаемое значение.

    execErr := syscall.Exec(binary, args, env)
    if execErr != nil {
        panic(execErr)
    }
}

Когда мы запускаем программу, она заменяется на ls.

$ go run execing-processes.go
total 16
drwxr-xr-x  4 mark 136B Oct 3 16:29 .
drwxr-xr-x 91 mark 3.0K Oct 3 12:50 ..
-rw-r--r--  1 mark 1.3K Oct 3 16:28 execing-processes.go

Обрати внимание, что Go не предоставляет классическую функцию Unix fork. Обычно это не проблема, поскольку запуск горутин, порождение и exec процессов покрывает большинство случаев использования fork.

Далее: .