2016-12-09 6 views
1

Что было бы эффективным способом убить процесс с помощью кода Go, если вы знаете только имя процесса? Я вижу некоторые функции, обеспечиваемые os пакета, как:Golang - процесс уничтожения по имени

func FindProcess(pid int) (*Process, error) 
func (p *Process) Kill() error 
func (p *Process) Signal(sig Signal) error 

Есть хороший/обычная практика, чтобы получить pid без выполнения команд, а затем разобрать выход?

Я нашел способ получить обратно ФИД, используя команду как следующее:

  • echo $(ps cax | grep myapp | grep -o '^[ ]*[0-9]*')

и я used it with exec.Command(), но я хотел бы избежать, если есть лучше подход.

+0

Возможный дубликат [Список в настоящее время работает процесс в Golang] (http://stackoverflow.com/questions/9030680/list-of-currently-running-process-in-golang) – I159

+0

Невозможно выполнить внешнюю команду. – Nadh

ответ

1

Я наконец использовал что-то вроде следующего:

// `echo "sudo_password" | sudo -S [command]` 
// is used in order to run the command with `sudo` 

_, err := exec.Command("sh", "-c", "echo '"+ sudopassword +"' | sudo -S pkill -SIGINT my_app_name").Output() 

if err != nil { 
    // ... 
} else { 
    // ... 
} 

Я использовал SIGINT сигнал корректно остановить приложение.

От wikipedia:

  • SIGINT

    Сигнал SIGINT посылается к процессу с помощью управляющего терминала, когда пользователь хочет прервать процесс. Обычно это инициируется нажатием Ctrl + C, но в некоторых системах может использоваться символ «удалить» или «разбить».

  • SIGKILL

    Сигнал SIGKILL посылается к процессу, чтобы заставить его прекратить немедленно (убить). В отличие от SIGTERM и SIGINT, этот сигнал не может быть пойман или проигнорирован, и процесс приема не может выполнить очистку при получении этого сигнала. Следующие исключения:

+0

Но как убить процесс, если мы не знаем pid? – Priyanka

+0

Вышеупомянутый фрагмент кода делает именно то, о чем вы просите. Вы не знаете «pid», но вам нужно знать «имя» исполняемого файла, который вы хотите убить. Например, здесь сигнал отправляется на 'my_app_name' – tgogos

+0

Ohh .. !! Я не видел код внимательно. Спасибо. – Priyanka

3

Выполнение внешних команд, вероятно, лучший способ сделать это. Однако следующий код работает на Ubuntu по крайней мере, пока вы являетесь владельцем процесса для уничтожения.

// killprocess project main.go 
package main 

import (
    "bytes" 
    "fmt" 
    "io" 
    "io/ioutil" 
    "log" 
    "os" 
    "path/filepath" 
    "strconv" 
    "strings" 
) 

// args holds the commandline args 
var args []string 

// findAndKillProcess walks iterative through the /process directory tree 
// looking up the process name found in each /proc/<pid>/status file. If 
// the name matches the name in the argument the process with the corresponding 
// <pid> will be killed. 
func findAndKillProcess(path string, info os.FileInfo, err error) error { 
    // We just return in case of errors, as they are likely due to insufficient 
    // privileges. We shouldn't get any errors for accessing the information we 
    // are interested in. Run as root (sudo) and log the error, in case you want 
    // this information. 
    if err != nil { 
     // log.Println(err) 
     return nil 
    } 

    // We are only interested in files with a path looking like /proc/<pid>/status. 
    if strings.Count(path, "/") == 3 { 
     if strings.Contains(path, "/status") { 

      // Let's extract the middle part of the path with the <pid> and 
      // convert the <pid> into an integer. Log an error if it fails. 
      pid, err := strconv.Atoi(path[6:strings.LastIndex(path, "/")]) 
      if err != nil { 
       log.Println(err) 
       return nil 
      } 

      // The status file contains the name of the process in its first line. 
      // The line looks like "Name: theProcess". 
      // Log an error in case we cant read the file. 
      f, err := ioutil.ReadFile(path) 
      if err != nil { 
       log.Println(err) 
       return nil 
      } 

      // Extract the process name from within the first line in the buffer 
      name := string(f[6:bytes.IndexByte(f, '\n')]) 

      if name == args[1] { 
       fmt.Printf("PID: %d, Name: %s will be killed.\n", pid, name) 
       proc, err := os.FindProcess(pid) 
       if err != nil { 
        log.Println(err) 
       } 
       // Kill the process 
       proc.Kill() 

       // Let's return a fake error to abort the walk through the 
       // rest of the /proc directory tree 
       return io.EOF 
      } 

     } 
    } 

    return nil 
} 

// main is the entry point of any go application 
func main() { 
    args = os.Args 
    if len(args) != 2 { 
     log.Fatalln("Usage: killprocess <processname>") 
    } 
    fmt.Printf("trying to kill process \"%s\"\n", args[1]) 

    err := filepath.Walk("/proc", findAndKillProcess) 
    if err != nil { 
     if err == io.EOF { 
      // Not an error, just a signal when we are done 
      err = nil 
     } else { 
      log.Fatal(err) 
     } 
    } 
} 

Это просто пример, который, безусловно, может быть улучшен. Я написал это для Linux и протестировал код на Ubuntu 15.10. Он не будет работать в Windows.

 Смежные вопросы

  • Нет связанных вопросов^_^