在Golang中通过名称或命令终止Linux进程

在Golang中通过名称或命令终止Linux进程 你好,我正在将一段 bash 代码转换为 Go 语言代码。 如果我运行 /usr/bin/getmykey &> /dev/null 并且想要终止该进程,那么在 bash 中我会运行这个命令:

ps aux | grep getmykey | grep -v grep | awk '{print "kill -9 " $2;system("kill -9 " $2)}'

我不想使用 bash,我想使用编译型语言,并且我已经用 Go 写好了代码,就剩这部分没写。 有没有一种简单的方法可以通过 Go 来终止进程?

4 回复

我们能否直接执行 pidof getmykey,然后将字符串分割成切片,获取第一个元素,再执行 kill -9 命令处理该元素?

更多关于在Golang中通过名称或命令终止Linux进程的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


与你遇到的其他转换问题类似。

尝试用等效的 Go 代码替换字符串操作和过滤。

这样你只需要两次调用 shell(暂时不引入系统调用),一次是通过 ps 获取进程列表,另一次是执行实际的 kill 操作。

可能存在也可能不存在现成的抽象层或库,能提供一个简单的函数来调用,以获取给定二进制文件名称的进程ID列表。

不过,通过调用 ps aux,扫描输出行以匹配给定模式,再调用 kill -p,这种方式编写起来可能比寻找为你做这些事情的库要快得多。

在Go中可以通过os/exec包执行命令来终止进程,也可以使用syscall包直接发送信号。以下是两种实现方式:

方法1:使用exec执行kill命令

package main

import (
    "os/exec"
    "strings"
)

func killProcessByName(name string) error {
    // 查找进程PID
    cmd := exec.Command("pgrep", "-f", name)
    output, err := cmd.Output()
    if err != nil {
        return err
    }

    pids := strings.Fields(string(output))
    for _, pid := range pids {
        // 发送SIGKILL信号
        killCmd := exec.Command("kill", "-9", pid)
        if err := killCmd.Run(); err != nil {
            return err
        }
    }
    return nil
}

// 使用示例
func main() {
    if err := killProcessByName("getmykey"); err != nil {
        // 处理错误
    }
}

方法2:使用syscall包直接发送信号

package main

import (
    "fmt"
    "os/exec"
    "strconv"
    "syscall"
)

func killProcessByNameSyscall(name string) error {
    cmd := exec.Command("pgrep", "-f", name)
    output, err := cmd.Output()
    if err != nil {
        return err
    }

    lines := strings.Fields(string(output))
    for _, line := range lines {
        pid, err := strconv.Atoi(line)
        if err != nil {
            continue
        }
        
        process, err := os.FindProcess(pid)
        if err != nil {
            continue
        }
        
        // 发送SIGKILL信号
        if err := process.Signal(syscall.SIGKILL); err != nil {
            return err
        }
    }
    return nil
}

// 使用示例
func main() {
    if err := killProcessByNameSyscall("getmykey"); err != nil {
        fmt.Printf("Error: %v\n", err)
    }
}

方法3:使用gopsutil第三方库(推荐)

package main

import (
    "github.com/shirou/gopsutil/process"
)

func killProcessByNameGopsutil(name string) error {
    processes, err := process.Processes()
    if err != nil {
        return err
    }

    for _, p := range processes {
        pname, err := p.Name()
        if err != nil {
            continue
        }
        
        if strings.Contains(pname, name) {
            if err := p.Kill(); err != nil {
                return err
            }
        }
    }
    return nil
}

// 使用前需要安装:go get github.com/shirou/gopsutil
func main() {
    if err := killProcessByNameGopsutil("getmykey"); err != nil {
        // 处理错误
    }
}

方法4:精确匹配进程名

package main

import (
    "os/exec"
    "strings"
)

func killExactProcess(command string) error {
    cmd := exec.Command("sh", "-c", 
        fmt.Sprintf("ps aux | grep '%s' | grep -v grep", command))
    output, err := cmd.Output()
    if err != nil {
        return err
    }

    lines := strings.Split(string(output), "\n")
    for _, line := range lines {
        if line == "" {
            continue
        }
        fields := strings.Fields(line)
        if len(fields) < 2 {
            continue
        }
        
        killCmd := exec.Command("kill", "-9", fields[1])
        killCmd.Run()
    }
    return nil
}

// 使用示例
func main() {
    killExactProcess("/usr/bin/getmykey")
}

这些方法都能实现通过进程名终止Linux进程。第一种方法最简单直接,第二种方法更底层,第三种方法功能最完整,第四种方法最接近你原来的bash实现。

回到顶部