2016-12-09 6 views
1

プロセス名のみを知っていれば、Goコードでプロセスを強制終了するにはどうすれば効果的でしょうか?私のようなosパッケージによって提供されるいくつかの機能を参照してください。ゴラン - 名前でプロセスを殺す

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()を持っていますが、よりよいがある場合、私はそれを避けたい:

私は、次のようなコマンドを使用してPIDを取り戻すための方法を発見しましたアプローチ。

+0

可能な複製(http://stackoverflow.com/questions/9030680/list-of-currently-running-process-in-golang) – I159

+0

外部コマンドを実行する以外に方法はありません。 – Nadh

答えて

1

は、私は最終的に次のようなものを使用しました。 wikipediaから

:ユーザはプロセスを中断したい場合

  • SIGINT

    SIGINT信号は、その制御端末によって、プロセスに送られます。これは通常、Ctrl + Cを押すことによって開始されますが、一部のシステムでは、「削除」文字または「中断」キーを使用できます。

  • SIGKILL

    SIGKILLシグナルは、それがすぐに(キル)を終了させるためのプロセスに送信されます。 SIGTERMおよびSIGINTとは対照的に、このシグナルは捕捉または無視することができず、受信プロセスはこのシグナルを受信して​​もクリーンアップを実行できません。以下の例外が適用されます。

[現在Golangでプロセスを実行しているのリスト]の
+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では動作しません。私は優雅にアプリを停止するSIGINT信号を使用

// `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 { 
    // ... 
} 

関連する問題