Go با مثال: اجرای پروسه با exec

در مثال قبل ایجاد پروسه‌های خارجی را دیدیم. این کار را وقتی انجام می‌دهیم که به یک پروسهٔ خارجی نیاز داریم که در دسترس پروسهٔ در حال اجرای Go باشد. اما گاهی فقط می‌خواهیم پروسهٔ فعلی Go را کاملاً با پروسهٔ دیگری (شاید غیر از Go) جایگزین کنیم. برای این کار از پیاده‌سازی Go برای تابع کلاسیک exec استفاده می‌کنیم.

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

در این مثال ls را exec می‌کنیم. 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 تابع کلاسیک fork یونیکس را ندارد. البته معمولاً این مشکلی نیست، چون راه‌اندازی گوروتین‌ها، ایجاد پروسه‌ها و exec کردن پروسه‌ها بیشتر کاربردهای fork را پوشش می‌دهند.

مثال بعدی: .