Go语言系统编程与命令行工具开发实战
引言
Go语言不仅适合Web开发,也是系统编程和命令行工具开发的绝佳选择。其简洁的语法、强大的标准库和跨平台能力,使其成为构建系统工具的理想语言。本文将深入探讨Go语言在系统编程中的应用,包括文件操作、进程管理、信号处理等核心技术。
一、命令行参数解析
1.1 使用flag包
package main import ( "flag" "fmt" ) func main() { // 定义命令行参数 name := flag.String("name", "World", "Name to greet") count := flag.Int("count", 1, "Number of greetings") verbose := flag.Bool("verbose", false, "Enable verbose output") // 解析参数 flag.Parse() // 使用参数 if *verbose { fmt.Printf("Name: %s, Count: %d\n", *name, *count) } for i := 0; i < *count; i++ { fmt.Printf("Hello, %s!\n", *name) } }1.2 使用pflag增强版
go get github.com/spf13/pflagimport "github.com/spf13/pflag" func main() { name := pflag.StringP("name", "n", "World", "Name to greet") count := pflag.IntP("count", "c", 1, "Number of greetings") pflag.Parse() fmt.Printf("Hello, %s! (x%d)\n", *name, *count) }1.3 使用Cobra框架
go get github.com/spf13/cobra@latestpackage main import ( "fmt" "github.com/spf13/cobra" ) func main() { var rootCmd = &cobra.Command{ Use: "greet", Short: "A simple greeting tool", Run: func(cmd *cobra.Command, args []string) { name, _ := cmd.Flags().GetString("name") fmt.Printf("Hello, %s!\n", name) }, } rootCmd.Flags().StringP("name", "n", "World", "Name to greet") rootCmd.Execute() }二、文件操作
2.1 文件读写
func readFile(path string) (string, error) { data, err := os.ReadFile(path) if err != nil { return "", err } return string(data), nil } func writeFile(path, content string) error { return os.WriteFile(path, []byte(content), 0644) }2.2 目录操作
func createDirectory(path string) error { return os.MkdirAll(path, 0755) } func listFiles(path string) ([]string, error) { entries, err := os.ReadDir(path) if err != nil { return nil, err } var files []string for _, entry := range entries { files = append(files, entry.Name()) } return files, nil }2.3 文件遍历
func walkDirectory(root string) error { return filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if err != nil { return err } fmt.Printf("%s (%d bytes)\n", path, info.Size()) return nil }) }三、进程管理
3.1 启动进程
func runCommand(cmd string, args ...string) error { c := exec.Command(cmd, args...) // 设置输出 c.Stdout = os.Stdout c.Stderr = os.Stderr return c.Run() } func main() { err := runCommand("ls", "-la") if err != nil { log.Fatal(err) } }3.2 获取进程输出
func getCommandOutput(cmd string, args ...string) (string, error) { output, err := exec.Command(cmd, args...).Output() if err != nil { return "", err } return string(output), nil }3.3 进程间通信
func pipeCommands() error { // 创建管道 ls := exec.Command("ls") grep := exec.Command("grep", ".go") // 连接输出 pipe, err := ls.StdoutPipe() if err != nil { return err } grep.Stdin = pipe // 设置输出 grep.Stdout = os.Stdout // 启动命令 ls.Start() grep.Run() return ls.Wait() }四、信号处理
4.1 捕获信号
func main() { sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) go func() { sig := <-sigChan fmt.Printf("\nReceived signal: %v\n", sig) fmt.Println("Cleaning up...") os.Exit(0) }() fmt.Println("Running... Press Ctrl+C to exit") select {} }4.2 优雅关闭
func main() { ctx, cancel := context.WithCancel(context.Background()) sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt) go func() { <-sigChan fmt.Println("Shutting down...") cancel() }() server := &http.Server{Addr: ":8080"} go func() { <-ctx.Done() server.Shutdown(ctx) }() log.Fatal(server.ListenAndServe()) }五、环境变量
5.1 读取环境变量
func getEnv(key, defaultValue string) string { value, exists := os.LookupEnv(key) if !exists { return defaultValue } return value } func main() { home := getEnv("HOME", "/home/user") fmt.Printf("Home directory: %s\n", home) }5.2 设置环境变量
func setEnv(key, value string) error { return os.Setenv(key, value) }六、系统信息
6.1 获取系统信息
func getSystemInfo() { hostname, _ := os.Hostname() fmt.Printf("Hostname: %s\n", hostname) // 获取CPU数量 fmt.Printf("CPU cores: %d\n", runtime.NumCPU()) // 获取内存信息 var memStats runtime.MemStats runtime.ReadMemStats(&memStats) fmt.Printf("Heap memory: %d MB\n", memStats.HeapAlloc/1024/1024) }6.2 操作系统检测
func getOS() string { switch runtime.GOOS { case "windows": return "Windows" case "linux": return "Linux" case "darwin": return "macOS" default: return "Unknown" } }七、日志记录
7.1 使用logrus
go get github.com/sirupsen/logrusfunc main() { log := logrus.New() // 设置日志级别 log.SetLevel(logrus.InfoLevel) // 设置格式 log.SetFormatter(&logrus.TextFormatter{ FullTimestamp: true, }) log.Info("Application started") log.Warn("Low memory warning") log.Error("Failed to connect to database") }7.2 配置文件处理
go get gopkg.in/yaml.v3type Config struct { Database struct { DSN string `yaml:"dsn"` } `yaml:"database"` Server struct { Port int `yaml:"port"` } `yaml:"server"` } func loadConfig(path string) (*Config, error) { data, err := os.ReadFile(path) if err != nil { return nil, err } var config Config err = yaml.Unmarshal(data, &config) return &config, err }八、实战案例:文件管理器
type FileManager struct{} func (fm *FileManager) List(path string) ([]FileInfo, error) { entries, err := os.ReadDir(path) if err != nil { return nil, err } var files []FileInfo for _, entry := range entries { info, _ := entry.Info() files = append(files, FileInfo{ Name: entry.Name(), Size: info.Size(), IsDir: entry.IsDir(), ModTime: info.ModTime(), }) } return files, nil } func (fm *FileManager) Copy(src, dst string) error { source, err := os.Open(src) if err != nil { return err } defer source.Close() destination, err := os.Create(dst) if err != nil { return err } defer destination.Close() _, err = io.Copy(destination, source) return err }九、性能监控工具
func monitorProcess(pid int) error { process, err := os.FindProcess(pid) if err != nil { return err } fmt.Printf("Monitoring process %d...\n", pid) // 定期检查进程状态 ticker := time.NewTicker(time.Second) for range ticker.C { err := process.Signal(syscall.Signal(0)) if err != nil { fmt.Println("Process has exited") return nil } fmt.Println("Process is running...") } return nil }十、跨平台开发
10.1 条件编译
//go:build windows // +build windows package main func getSeparator() string { return "\\" }//go:build !windows // +build !windows package main func getSeparator() string { return "/" }结论
Go语言在系统编程领域展现出强大的能力。通过标准库和丰富的第三方库,Go可以轻松处理文件操作、进程管理、信号处理等任务。其跨平台特性和高性能使其成为构建系统工具的理想选择。无论是简单的命令行工具还是复杂的系统管理软件,Go都能胜任。