52 lines
1.7 KiB
Go
52 lines
1.7 KiB
Go
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"log"
|
||
"os"
|
||
"os/exec"
|
||
)
|
||
|
||
// Daemon 函数用于将程序转换为守护进程模式(简易实现)
|
||
// 注意:这不是 POSIX 标准的完整守护进程实现,缺少以下标准步骤:
|
||
// 1. 未创建新会话(setsid)
|
||
// 2. 未重置文件权限掩码
|
||
// 3. 未改变工作目录
|
||
// 4. 未关闭/重定向标准输入输出
|
||
// 适用于简单后台需求,生产环境建议使用专业库
|
||
func Daemon() {
|
||
// 构建新的命令行参数(过滤掉 -d 参数)
|
||
args := make([]string, 0)
|
||
for _, arg := range os.Args[1:] { // 遍历原始参数(跳过第一个程序路径参数)
|
||
if arg != "-d" { // 过滤掉用于触发守护进程的 -d 标志
|
||
args = append(args, arg)
|
||
}
|
||
}
|
||
|
||
// 创建新的进程命令
|
||
// os.Args[0] 是当前程序的执行路径
|
||
// args 是过滤后的新参数列表(不包含 -d)
|
||
cmd := exec.Command(os.Args[0], args...)
|
||
|
||
// 配置标准输入输出(注意:真正的守护进程通常需要重定向这些)
|
||
// 这里继承父进程的标准输入输出,实际使用时可能需要:
|
||
// 1. 重定向到文件
|
||
// 2. 指向 /dev/null
|
||
// 3. 使用日志系统
|
||
cmd.Stdout = os.Stdout
|
||
cmd.Stderr = os.Stderr
|
||
|
||
// 异步启动新进程(Start 而非 Run)
|
||
// 注意:此处未设置新进程组或会话,可能导致子进程随终端关闭
|
||
if err := cmd.Start(); err != nil {
|
||
log.Fatalf("无法启动新实例: %v", err) // 启动失败时终止父进程
|
||
}
|
||
|
||
// 输出提示信息(调试用,正式版可删除)
|
||
fmt.Println("新实例已启动,当前进程将退出")
|
||
|
||
// 退出父进程,让子进程继续运行
|
||
// 注意:此时子进程的父进程变为 init 进程(PID 1)
|
||
os.Exit(0)
|
||
}
|