pid获取


pid获取

pidof 在arm环境下 有bug

GetProcessPid

package pid

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"strconv"
	"strings"
)

// IsExist checks whether a file or directory exists.
// It returns false when the file or directory does not exist.
func isExist(fp string) bool {
	_, err := os.Stat(fp)
	return err == nil || os.IsExist(err)
}

// DirsUnder list dirs under dirPath
func dirsUnder(dirPath string) ([]string, error) {
	if !isExist(dirPath) {
		return []string{}, nil
	}

	fs, err := ioutil.ReadDir(dirPath)
	if err != nil {
		return []string{}, err
	}

	sz := len(fs)
	if sz == 0 {
		return []string{}, nil
	}

	ret := make([]string, 0, sz)
	for i := 0; i < sz; i++ {
		if fs[i].IsDir() {
			name := fs[i].Name()
			if name != "." && name != ".." {
				ret = append(ret, name)
			}
		}
	}

	return ret, nil
}

func readName(path string) (name string, err error) {
	var content []byte
	content, err = ioutil.ReadFile(path)
	if err != nil {
		return
	}

	reader := bufio.NewReader(bytes.NewBuffer(content))

	for {
		var bs []byte
		bs, err = readLine(reader)
		if err == io.EOF {
			return
		}

		line := string(bs)
		colonIndex := strings.Index(line, ":")

		if strings.TrimSpace(line[0:colonIndex]) == "Name" {
			return strings.TrimSpace(line[colonIndex+1:]), nil
		}

	}

	return
}

func readLine(r *bufio.Reader) ([]byte, error) {
	line, isPrefix, err := r.ReadLine()
	for isPrefix && err == nil {
		var bs []byte
		bs, isPrefix, err = r.ReadLine()
		line = append(line, bs...)
	}

	return line, err
}

// GetProcessPid 获取某个进程的进程号
func GetProcessPid(processName string) (procId int) {
	dirs, err := dirsUnder("/proc")
	if err != nil {
		return
	}

	size := len(dirs)
	if size == 0 {
		return
	}

	for i := 0; i < size; i++ {
		pid, e := strconv.Atoi(dirs[i])
		if e != nil {
			continue
		}

		statusFile := fmt.Sprintf("/proc/%d/status", pid)
		if !isExist(statusFile) {
			continue
		}

		name, e := readName(statusFile)
		if e != nil {
			continue
		}

		if name == processName {
			procId, _ = strconv.Atoi(dirs[i])
			break
		}
	}

	return
}