Go语言系统编程与命令行工具
Go语言系统编程与命令行工具
一、命令行参数解析
Go语言提供了多个标准库来处理命令行参数,包括flag包和os包。
使用flag包
package main import ( "flag" "fmt" ) func main() { // 定义命令行参数 name := flag.String("name", "Guest", "User name") age := flag.Int("age", 18, "User age") verbose := flag.Bool("verbose", false, "Enable verbose mode") // 解析参数 flag.Parse() fmt.Printf("Name: %s\n", *name) fmt.Printf("Age: %d\n", *age) fmt.Printf("Verbose: %v\n", *verbose) // 解析剩余的非flag参数 fmt.Printf("Args: %v\n", flag.Args()) }使用pflag包
go get github.com/spf13/pflagpackage main import ( "fmt" "github.com/spf13/pflag" ) func main() { name := pflag.StringP("name", "n", "Guest", "User name") age := pflag.IntP("age", "a", 18, "User age") verbose := pflag.BoolP("verbose", "v", false, "Enable verbose mode") pflag.Parse() fmt.Printf("Name: %s\n", *name) fmt.Printf("Age: %d\n", *age) fmt.Printf("Verbose: %v\n", *verbose) }二、文件操作
文件读写
package main import ( "fmt" "io/ioutil" "os" ) func main() { // 写入文件 err := ioutil.WriteFile("example.txt", []byte("Hello, World!"), 0644) if err != nil { fmt.Printf("Write error: %v\n", err) return } // 读取文件 content, err := ioutil.ReadFile("example.txt") if err != nil { fmt.Printf("Read error: %v\n", err) return } fmt.Printf("File content: %s\n", content) }文件操作进阶
package main import ( "bufio" "fmt" "os" ) func main() { // 打开文件 file, err := os.OpenFile("example.txt", os.O_RDWR|os.O_CREATE, 0644) if err != nil { fmt.Printf("Open error: %v\n", err) return } defer file.Close() // 写入数据 writer := bufio.NewWriter(file) _, err = writer.WriteString("Hello, Go!\n") if err != nil { fmt.Printf("Write error: %v\n", err) return } writer.Flush() // 读取数据 file.Seek(0, 0) scanner := bufio.NewScanner(file) for scanner.Scan() { fmt.Println(scanner.Text()) } if err := scanner.Err(); err != nil { fmt.Printf("Scan error: %v\n", err) } }三、进程管理
启动子进程
package main import ( "fmt" "os/exec" ) func main() { // 执行命令 cmd := exec.Command("echo", "Hello, World!") output, err := cmd.CombinedOutput() if err != nil { fmt.Printf("Command error: %v\n", err) return } fmt.Printf("Output: %s\n", output) }带管道的进程
package main import ( "fmt" "os/exec" "io" ) func main() { // 创建两个命令 cmd1 := exec.Command("echo", "Hello, Go!") cmd2 := exec.Command("tr", "a-z", "A-Z") // 连接管道 pipe, err := cmd1.StdoutPipe() if err != nil { fmt.Printf("Pipe error: %v\n", err) return } cmd2.Stdin = pipe // 启动命令 err = cmd1.Start() if err != nil { fmt.Printf("Start cmd1 error: %v\n", err) return } output, err := cmd2.CombinedOutput() if err != nil { fmt.Printf("Cmd2 error: %v\n", err) return } cmd1.Wait() fmt.Printf("Output: %s\n", output) }四、信号处理
package main import ( "fmt" "os" "os/signal" "syscall" "time" ) func main() { // 创建信号通道 sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) // 启动业务逻辑 go func() { for { fmt.Println("Working...") time.Sleep(1 * time.Second) } }() // 等待信号 sig := <-sigChan fmt.Printf("\nReceived signal: %v\n", sig) // 清理资源 fmt.Println("Cleaning up...") fmt.Println("Exiting...") }五、环境变量
package main import ( "fmt" "os" ) func main() { // 获取环境变量 home := os.Getenv("HOME") fmt.Printf("HOME: %s\n", home) // 设置环境变量 err := os.Setenv("MY_APP_ENV", "production") if err != nil { fmt.Printf("Setenv error: %v\n", err) return } // 获取所有环境变量 env := os.Environ() for _, e := range env { fmt.Println(e) } // 检查环境变量是否存在 _, exists := os.LookupEnv("MY_APP_ENV") fmt.Printf("MY_APP_ENV exists: %v\n", exists) }六、系统信息
package main import ( "fmt" "os" "runtime" ) func main() { // 获取操作系统信息 fmt.Printf("OS: %s\n", runtime.GOOS) fmt.Printf("Arch: %s\n", runtime.GOARCH) fmt.Printf("CPU cores: %d\n", runtime.NumCPU()) // 获取进程信息 fmt.Printf("Process ID: %d\n", os.Getpid()) fmt.Printf("Parent PID: %d\n", os.Getppid()) // 获取当前工作目录 cwd, err := os.Getwd() if err != nil { fmt.Printf("Getwd error: %v\n", err) return } fmt.Printf("Current directory: %s\n", cwd) }七、命令行工具框架
使用Cobra
go get github.com/spf13/cobra@latestpackage main import ( "fmt" "os" "github.com/spf13/cobra" ) func main() { var rootCmd = &cobra.Command{ Use: "myapp", Short: "A simple command line tool", Long: `MyApp is a demonstration of Cobra commands`, Run: func(cmd *cobra.Command, args []string) { fmt.Println("Hello from MyApp!") }, } var echoCmd = &cobra.Command{ Use: "echo [message]", Short: "Echo the message", Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { upper, _ := cmd.Flags().GetBool("upper") message := args[0] if upper { message = strings.ToUpper(message) } fmt.Println(message) }, } echoCmd.Flags().BoolP("upper", "u", false, "Convert to uppercase") rootCmd.AddCommand(echoCmd) if err := rootCmd.Execute(); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } }八、日志工具
使用logrus
go get github.com/sirupsen/logruspackage main import ( "github.com/sirupsen/logrus" ) func main() { log := logrus.New() // 设置日志级别 log.SetLevel(logrus.DebugLevel) // 设置输出格式 log.SetFormatter(&logrus.JSONFormatter{}) // 不同级别的日志 log.Debug("Debug message") log.Info("Info message") log.Warn("Warn message") log.Error("Error message") // 带字段的日志 log.WithFields(logrus.Fields{ "user": "john", "id": 42, }).Info("User logged in") }九、配置文件处理
使用toml配置
go get github.com/BurntSushi/tomlpackage main import ( "fmt" "os" "github.com/BurntSushi/toml" ) type Config struct { Database struct { Host string `toml:"host"` Port int `toml:"port"` Database string `toml:"database"` } `toml:"database"` Server struct { Port int `toml:"port"` } `toml:"server"` } func main() { config := Config{} file, err := os.Open("config.toml") if err != nil { fmt.Printf("Open config error: %v\n", err) return } defer file.Close() _, err = toml.DecodeReader(file, &config) if err != nil { fmt.Printf("Decode error: %v\n", err) return } fmt.Printf("DB Host: %s\n", config.Database.Host) fmt.Printf("DB Port: %d\n", config.Database.Port) }配置文件示例:
[database] host = "localhost" port = 3306 database = "example_db" [server] port = 8080十、总结
Go语言提供了丰富的系统编程能力,通过标准库可以轻松实现:
- 命令行参数解析:使用flag或pflag包
- 文件操作:读写文件、目录操作
- 进程管理:启动子进程、管道通信
- 信号处理:捕获系统信号
- 环境变量:获取和设置环境变量
- 系统信息:获取OS、CPU、进程信息
- 命令行框架:使用Cobra构建复杂CLI工具
- 日志记录:使用logrus等日志库
- 配置文件:支持多种配置格式
掌握这些系统编程能力可以帮助你构建强大的命令行工具和系统应用。
