[英]Check if a process exists in go way
如果我有進程的 PID, os.FindProcess 是否足以測試進程的存在? 我的意思是如果它返回err
,我可以假設它已終止(或被殺死)嗎?
編輯:
我剛剛圍繞kill -s 0
(舊式 bash 進程測試)編寫了一個包裝函數。 這沒有任何問題,但如果有其他解決方案(使用 go 庫完成)解決此問題,我仍然很高興。:
func checkPid(pid int) bool {
out, err := exec.Command("kill", "-s", "0", strconv.Itoa(pid)).CombinedOutput()
if err != nil {
log.Println(err)
}
if string(out) == "" {
return true // pid exist
}
return false
}
這是查看進程是否處於活動狀態的傳統 unix 方法 - 向其發送 0 信號(就像您在 bash 示例中所做的那樣)。
從kill(2)
:
If sig is 0, then no signal is sent, but error checking is still per‐ formed; this can be used to check for the existence of a process ID or process group ID.
並翻譯成 Go
package main
import (
"fmt"
"log"
"os"
"strconv"
"syscall"
)
func main() {
for _, p := range os.Args[1:] {
pid, err := strconv.ParseInt(p, 10, 64)
if err != nil {
log.Fatal(err)
}
process, err := os.FindProcess(int(pid))
if err != nil {
fmt.Printf("Failed to find process: %s\n", err)
} else {
err := process.Signal(syscall.Signal(0))
fmt.Printf("process.Signal on pid %d returned: %v\n", pid, err)
}
}
}
當你運行它時,你會得到這個,表明進程 123 已死,進程 1 處於活動狀態但不歸您所有,而進程 12606 處於活動狀態並歸您所有。
$ ./kill 1 $$ 123
process.Signal on pid 1 returned: operation not permitted
process.Signal on pid 12606 returned: <nil>
process.Signal on pid 123 returned: no such process
在類 Unix 系統(linux、freebsd 等)上,os.FindProcess 永遠不會返回錯誤。 我不知道在 Windows 上會發生什么。 這意味着在您嘗試使用 *os.Process 之前,您不會知道 PID 是否正確。
您可以在此處查看代碼。
您也可以只使用syscall.Kill
。 它相當於更少的代碼。
killErr := syscall.Kill(pid, syscall.Signal(0))
procExists := killErr == nil
如果在系統中找不到先前已知的 pid(不確定 go 函數),則意味着進程肯定已終止並已加入(在 Unix 上,使用wait call )。
但其他方式不一定正確。 僅僅因為 pid 存在,它並不能保證它與以前的過程相同。 例如,在標准 Linux 中只有 65535 個有效的 pid,當有回繞時它們可以被重用。 但是,如果您經常檢查,出於實際目的,您不需要關心這一點(只要發現錯誤的新進程的 pid 不是安全漏洞或其他關鍵的東西,有人可能會試圖故意觸發惡意目的)。
相關鏈接(及其右欄中的相關問題):
到目前為止所有的答案都是不完整的實現。 請參閱https://github.com/shirou/gopsutil/blob/c141152a7b8f59b63e060fa8450f5cd5e7196dfb/process/process_posix.go#L73以獲得更完整的實現(復制內聯)
func PidExists(pid int32) (bool, error) {
if pid <= 0 {
return false, fmt.Errorf("invalid pid %v", pid)
}
proc, err := os.FindProcess(int(pid))
if err != nil {
return false, err
}
err = proc.Signal(syscall.Signal(0))
if err == nil {
return true, nil
}
if err.Error() == "os: process already finished" {
return false, nil
}
errno, ok := err.(syscall.Errno)
if !ok {
return false, err
}
switch errno {
case syscall.ESRCH:
return false, nil
case syscall.EPERM:
return true, nil
}
return false, err
}
在 Windows 上檢查os.FindProcess()
的結果似乎足以檢查進程是否正在運行。
func isProcessRunning(pid int) bool {
_, err = os.FindProcess(pid)
if err != nil {
return false
}
if runtime.GOOS == "windows" {
return true
}
return false // further checking for other systems then Windows is not supported here
}
經過幾個小時的搜索,了解進程是否在 Windows 上運行的正確答案如下:
func CheckProcessLife(pid int){
cmd,_ := exec.Command("tasklist","/FI", "PID eq " + strconv.Itoa(pid)).Output()
output := string(cmd[:])
splitOutp := strings.Split(output, " ")
if !(splitOutp[1] == "no") {
time.Sleep(500 * time.Millisecond)
fmt.Println("Process is running...")
CheckProcessLife(pid)
}else{
fmt.Println("Process is no longer running.")
}
}
您可以檢查進程是否使用他的 PID 或直接使用他的名字運行,只需更改此行:
cmd,_ := exec.Command("tasklist","/FI", "IMAGENAME eq yourprocessname.exe").Output()
這是如何檢查進程是否存在/在 Windows 上使用 Golang 運行的一種方法。
我們執行命令:
TASKLIST /V /NH /FI "PID eq 23232"
哪個可以返回:
INFO: No tasks are running which match the specified criteria.
或者如果找到:
Image Name PID Session Name Session# Mem Usage Status User Name CPU Time Window Title
========================= ======== ================ =========== ============ =============== ================================================== ============ ========================================================================
chrome.exe 23232 Console 1 42,472 K Unknown THANOS\MARVEL 0:00:00 N/A
這是一個利用此信息的函數。
func isProcessRunning(pid int) bool {
cmd := exec.Command("TASKLIST", "/FI", fmt.Sprintf("PID eq %d", pid))
result, err := cmd.Output()
if err != nil {
return false
}
return !bytes.Contains(result, []byte("No tasks are running"))
}
最好的事情是你也可以通過其他參數找到過程:
ImageName eq, ne Image Name String
PID eq, ne, gt, lt, ge, le Process ID, A Positive integer.
Session eq, ne, gt, lt, ge, le Any valid session number.
SessionName eq, ne String
Status eq, ne RUNNING | NOT RESPONDING | UNKNOWN
CPUTime eq, ne, gt, lt, ge, le Time hh:mm:ss
MemUsage eq, ne, gt, lt, ge, le Memory usage in KB, specify a valid integer.
Username eq, ne User name ([Domain\]User).
Services eq, ne Service Name String
Windowtitle eq, ne Window Title String
Modules eq, ne DLL Name String
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.