I am new in GO and mac, and I'm trying to use sysctl for finding the full path name of running processes.
kprocs, err := unix.SysctlKinfoProcSlice("kern.proc.all")
if err != nil {
fmt.Println("error: ", err)
}
for _, proc := range kprocs {
name := string(proc.Proc.P_comm[:])
pid := proc.Proc.P_pid
extName, err := unix.SysctlKinfoProc("kern.proc.pathname", int(pid))
if err != nil {
fmt.Println("error: ", err)
}
and getting error: no such file or directory
am I using this function correcly?
EDIT
If I run the process like this: ./processName ,then I am not getting it's full path, for example /Users/username/go/src/processName - which is what I need.
All the solutions with ps
will give the relative path, and I need someting that gives the absolute path of the process.
CodePudding user response:
Here you go:
func printPath(pid int32) {
cmd := exec.Command("ps", append([]string{"xuwww", "-p", strconv.Itoa(int(pid))})...)
output, e := cmd.CombinedOutput()
if e != nil {
fmt.Println(e)
}
lines := strings.Split(string(output), "\n")
comps := strings.Fields(lines[1])
fmt.Println(comps[len(comps)-1])
}
func main() {
kprocs, err := unix.SysctlKinfoProcSlice("kern.proc.all")
if err != nil {
fmt.Println("error: ", err)
}
for _, proc := range kprocs {
pid := proc.Proc.P_pid
printPath(pid)
}
}
I didn't use unix.SysctlKinfoProc(), instead ran a shell command ps xuwww -p PID
using exec.command(). It returns output as string. Parse the output string to get absolute path.
Output:
649 /System/Library/PrivateFrameworks/IMDPersistence.framework/XPCServices/IMDPersistenceAgent.xpc/Contents/MacOS/IMDPersistenceAgent 646 /System/Library/PrivateFrameworks/AuthKit.framework/Versions/A/Support/akd 643 /System/Library/CoreServices/pbs
CodePudding user response:
Following my comment on your question you can get the information you are looking for by using lsof.
Similar to the other code example you can iterate over all known processes but for some processes it takes some time for the command to return.
package main
import (
"fmt"
"os/exec"
"golang.org/x/sys/unix"
)
func printPath(pid int32) {
cmd := exec.Command("bash", "-c", fmt.Sprintf("lsof -p %d -Fn | awk 'NR==5{print}' | sed \"s/n\\//\\//\"", pid))
output, e := cmd.CombinedOutput()
if e != nil {
fmt.Println(e)
return
}
fmt.Printf("%s", output)
}
func main() {
kprocs, err := unix.SysctlKinfoProcSlice("kern.proc.all")
if err != nil {
fmt.Println("error: ", err)
}
for _, proc := range kprocs {
pid := proc.Proc.P_pid
fmt.Printf("getting for pid %d: ", pid)
printPath(pid)
}
}
The code output can be improved. Processes that have exited already now make the output kind of a mess :-/