Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terminating a Process Started with os/exec in Golang

Tags:

go

Is there a way to terminate a process started with os.exec in Golang? For example (from http://golang.org/pkg/os/exec/#example_Cmd_Start),

cmd := exec.Command("sleep", "5") err := cmd.Start() if err != nil {     log.Fatal(err) } log.Printf("Waiting for command to finish...") err = cmd.Wait() log.Printf("Command finished with error: %v", err) 

Is there a way to terminate that process ahead of time, perhaps after 3 seconds?

Thanks in advance

like image 844
Tech163 Avatar asked Aug 09 '12 15:08

Tech163


People also ask

How do I terminate a process in Golang?

The provided context is used to kill the process (by calling os. Process. Kill) if the context becomes done before the command completes on its own. After the Run() completes, you can inspect ctx.

How to terminate exec command in linux?

Note that the job ID should be prefixed with % , or kill will consider it a PID. kill can work without specifying a signal explicitly. In that case, the default action is to send SIGTERM , which will terminate the process. Execute kill -l to list all signal names, and use the man kill command to read the man page.

What is Golang exec?

It is simply a sub-package that allows you to execute external commands using Go.


1 Answers

Run and terminate an exec.Process:

// Start a process: cmd := exec.Command("sleep", "5") if err := cmd.Start(); err != nil {     log.Fatal(err) }  // Kill it: if err := cmd.Process.Kill(); err != nil {     log.Fatal("failed to kill process: ", err) } 

Run and terminate an exec.Process after a timeout:

ctx, cancel := context.WithTimeout(context.Background(), 3 * time.Second) defer cancel()  if err := exec.CommandContext(ctx, "sleep", "5").Run(); err != nil {     // This will fail after 3 seconds. The 5 second sleep     // will be interrupted. } 

See this example in the Go docs


Legacy

Before Go 1.7, we didn't have the context package and this answer was different.

Run and terminate an exec.Process after a timeout using channels and a goroutine:

// Start a process: cmd := exec.Command("sleep", "5") if err := cmd.Start(); err != nil {     log.Fatal(err) }  // Wait for the process to finish or kill it after a timeout (whichever happens first): done := make(chan error, 1) go func() {     done <- cmd.Wait() }() select { case <-time.After(3 * time.Second):     if err := cmd.Process.Kill(); err != nil {         log.Fatal("failed to kill process: ", err)     }     log.Println("process killed as timeout reached") case err := <-done:     if err != nil {         log.Fatalf("process finished with error = %v", err)     }     log.Print("process finished successfully") } 

Either the process ends and its error (if any) is received through done or 3 seconds have passed and the program is killed before it's finished.

like image 95
Zippo Avatar answered Oct 02 '22 19:10

Zippo