В предишния пример разгледахме създаването на външни
процеси. Това го правим, когато искаме да имаме външен
процес, който да достъпваме от работещ Го процес. Понякога пък искаме
напълно да заместим текущия процес с друг, може би не написан на Го. За да
направим това, ще ползваме класическата функция exec1, както е
осъществена в Го.
import (
"os"
"os/exec"
"syscall"
)
func main() {
В нашия случай ще изпълним юникс командата ls. Го изисква абсолютен
пѫт до изпълнимия файл, затова ползваме 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
общо 20K
drwxr-xr-x 2 berov berov 4,0K 18 юни 16:01 .
drwxr-xr-x 87 berov berov 4,0K 17 яну 14:27 ..
-rw-r--r-- 1 berov berov 2,3K 18 юни 15:47 execing-processes.go
-rw-r--r-- 1 berov berov 53 18 юни 16:03 execing-processes.hash
-rw-r--r-- 1 berov berov 666 18 юни 16:01 execing-processes.sh
Забележете, че Го не предлага класическата в Юникс функция fork. Обикновено
това не създава пречки, понеже гозадачите, пораждането и изпълнението
на процеси покриват повечето от случаите, в които се ползва fork.
Следващ пример: Сигнали.