pid & stop

This commit is contained in:
gotoeasy 2022-09-14 11:44:13 +08:00
parent da22db315b
commit 467ebe4b48
2 changed files with 89 additions and 35 deletions

View File

@ -16,33 +16,76 @@ func init() {
return
}
// pid
pidfile := NewPid("~/.gologcenter/glc.pid")
if pidfile.Err != nil {
os.Exit(1) // 创建或保存pid文件失败
}
pidfile := "~/.gologcenter/glc.pid"
if !pidfile.IsNew {
log.Println(pidfile.Pid)
os.Exit(0) // 进程已存在,不重复启动
}
// 操作系统是linux时支持以命令行参数【-d】后台方式启动
// 操作系统是linux时支持以命令行参数【-d】后台方式启动【stop】停止
daemon := false
stop := false
for index, arg := range os.Args {
if index > 0 && arg == "-d" {
if index == 0 {
continue
}
if arg == "-d" {
daemon = true
break
}
if arg == "stop" {
stop = true
}
}
// 停止
if stop {
tmpPid := readPid(pidfile)
if tmpPid != "" {
exec.Command("sh", "-c", "kill "+tmpPid)
}
os.Exit(0)
}
// 启动守护进程
if daemon {
// 已启动时忽略
chk := checkPidFile(pidfile)
if chk != nil {
log.Println(chk.Pid)
os.Exit(0) // 进程已存在,不重复启动
}
// 启动失败则退出
cmd := exec.Command(os.Args[0], flag.Args()...)
if err := cmd.Start(); err != nil {
fmt.Printf("start %s failed, error: %v\n", os.Args[0], err)
os.Exit(1)
}
fmt.Printf("%s [PID] %d running\n", os.Args[0], cmd.Process.Pid)
// 启动成功则保存pid
daemonPid := fmt.Sprintf("%d", cmd.Process.Pid)
err := savePid(pidfile, daemonPid)
if err != nil {
// 保存pid失败则退出
exec.Command("sh", "-c", "kill "+daemonPid)
os.Exit(1) // 创建或保存pid文件失败
}
log.Println(daemonPid)
os.Exit(0)
}
// 普通启动
// 已启动时忽略
chk := checkPidFile(pidfile)
if chk != nil {
log.Println(chk.Pid)
os.Exit(0) // 进程已存在,不重复启动
}
// 保存pid失败则退出
pid := fmt.Sprintf("%d", os.Getpid())
err := savePid(pidfile, pid)
if err != nil {
exec.Command("sh", "-c", "kill "+pid)
os.Exit(1) // 创建或保存pid文件失败
}
}

View File

@ -1,7 +1,6 @@
package onstart
import (
"fmt"
"log"
"os"
"path/filepath"
@ -16,25 +15,15 @@ type PidFile struct {
}
// 指定路径下生成pid文件文件内容为pid已存在时检查pid有效性
func NewPid(pathfile string) *PidFile {
func NewPid(pathfile string, pid string) *PidFile {
// 运行中时直接返回
if opid := checkPidFile(pathfile); opid != nil {
return opid
}
// 创建文件
if err := os.MkdirAll(filepath.Dir(pathfile), os.FileMode(0755)); err != nil {
log.Println("create pid file failed", pathfile)
return &PidFile{
Path: pathfile,
Err: err,
}
}
// 保存PID
pid := fmt.Sprintf("%d", os.Getpid())
if err := os.WriteFile(pathfile, []byte(pid), 0644); err != nil {
if err := savePid(pathfile, pid); err != nil {
log.Println("save pid file failed", pathfile)
return &PidFile{
Path: pathfile,
@ -53,15 +42,37 @@ func NewPid(pathfile string) *PidFile {
}
func checkPidFile(path string) *PidFile {
if pidByte, err := os.ReadFile(path); err == nil {
pid := strings.TrimSpace(string(pidByte))
if _, err := os.Stat(filepath.Join("/proc", pid)); err == nil {
return &PidFile{
Path: path,
Pid: pid,
IsNew: false,
}
pid := readPid(path)
if pid == "" {
return nil
}
if _, err := os.Stat(filepath.Join("/proc", pid)); err == nil {
return &PidFile{
Path: path,
Pid: pid,
IsNew: false,
}
}
return nil
}
func readPid(path string) string {
if pidByte, err := os.ReadFile(path); err == nil {
return strings.TrimSpace(string(pidByte))
}
return ""
}
func savePid(path string, pid string) error {
if err := os.MkdirAll(filepath.Dir(path), os.FileMode(0755)); err != nil {
log.Println("create pid file failed", path)
return err
}
if err := os.WriteFile(path, []byte(pid), 0644); err != nil {
log.Println("save pid file failed", path)
return err
}
return nil
}