package system import ( "fmt" "os" "os/exec" "strings" ) // SetHostname 设置系统主机名 // 参数: hostname - 目标主机名 // 返回: error - 如果设置失败返回错误信息 func SetHostname(hostname string) error { if hostname == "" { return nil // 空值跳过,不报错 } // 检查是否已有相同主机名 current, err := os.Hostname() if err == nil && current == hostname { return nil // 已经设置正确,无需修改 } // 使用 hostnamectl 设置主机名(适用于 systemd 系统) if _, err := exec.LookPath("hostnamectl"); err == nil { cmd := exec.Command("hostnamectl", "set-hostname", hostname) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return fmt.Errorf("hostnamectl 设置主机名失败: %v", err) } } else { // 传统方法:直接修改 /etc/hostname if err := os.WriteFile("/etc/hostname", []byte(hostname+"\n"), 0644); err != nil { return fmt.Errorf("写入 /etc/hostname 失败: %v", err) } // 立即生效(需要内核支持) cmd := exec.Command("sysctl", "kernel.hostname="+hostname) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { // 不返回错误,因为重启后会生效 fmt.Printf("警告: 主机名将在重启后完全生效\n") } } // 更新 /etc/hosts,确保本机解析正确 if err := updateHostsFile(hostname); err != nil { fmt.Printf("警告: 更新 /etc/hosts 失败: %v\n", err) } return nil } // updateHostsFile 更新 /etc/hosts 文件中的本机映射 func updateHostsFile(hostname string) error { content, err := os.ReadFile("/etc/hosts") if err != nil { return err } lines := strings.Split(string(content), "\n") newLines := make([]string, 0, len(lines)) hostnameSet := false for _, line := range lines { // 跳过空行和注释 if line == "" || strings.HasPrefix(line, "#") { newLines = append(newLines, line) continue } fields := strings.Fields(line) if len(fields) >= 2 && fields[0] == "127.0.1.1" { // 替换 Ubuntu/Debian 风格的本地主机名 newLines = append(newLines, "127.0.1.1\t"+hostname) hostnameSet = true } else if len(fields) >= 2 && fields[0] == "127.0.0.1" { // 保留原行,但检查是否包含主机名 if !strings.Contains(line, hostname) { line = line + " " + hostname } newLines = append(newLines, line) hostnameSet = true } else { newLines = append(newLines, line) } } // 如果没有找到合适的位置,添加一行 if !hostnameSet { newLines = append(newLines, "127.0.1.1\t"+hostname) } return os.WriteFile("/etc/hosts", []byte(strings.Join(newLines, "\n")), 0644) }