Go语言技术与应用(六):命令行工具开发基础
命令行工具在日常开发中用得很多,比如git、docker这些我们天天用的工具。Go语言写命令行程序特别方便,语法简单,编译后就是一个可执行文件,部署起来很轻松。
这篇文章会带你从零开始,学会用Go写命令行工具的基础知识。主要涉及两个核心内容:如何处理命令行参数和如何获取用户输入。
1. 命令行参数处理
1.1 os.Args基础用法
Go语言内置的os.Args是个字符串切片,专门用来获取命令行参数。它有个特点:第一个元素永远是程序本身的名字,从第二个元素开始才是用户传入的参数。
来看个简单例子:
package main
import (
"fmt"
"os" // 别忘了导入os包
)
func main() {
// 检查是否有参数传入
if len(os.Args) > 1 {
fmt.Println("你传入的参数有:")
// 从索引1开始遍历,跳过程序名
for i, arg := range os.Args[1:] {
fmt.Printf("参数%d: %s\n", i+1, arg)
}
} else {
fmt.Println("没有传入任何参数")
}
// 顺便看看程序名是什么
fmt.Printf("程序名: %s\n", os.Args[0])
}
1.2 实际应用场景
假设我们要写一个简单的文件操作工具,可以根据不同参数执行不同操作:
package main
import (
"fmt"
"os"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("用法: ./tool <命令> [参数]")
fmt.Println("支持的命令: list, create, delete")
return
}
command := os.Args[1] // 获取第一个参数作为命令
switch command {
case "list":
fmt.Println("列出文件...")
// 这里可以添加列出文件的逻辑
case "create":
if len(os.Args) < 3 {
fmt.Println("create命令需要文件名参数")
return
}
filename := os.Args[2]
fmt.Printf("创建文件: %s\n", filename)
// 这里可以添加创建文件的逻辑
case "delete":
if len(os.Args) < 3 {
fmt.Println("delete命令需要文件名参数")
return
}
filename := os.Args[2]
fmt.Printf("删除文件: %s\n", filename)
// 这里可以添加删除文件的逻辑
default:
fmt.Printf("未知命令: %s\n", command)
}
}
2. 用户输入处理
2.1 bufio包的使用
有时候我们需要在程序运行过程中让用户输入一些内容,这时候就要用到bufio包了。它提供了缓冲读取功能,处理用户输入很方便。
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
// 创建一个从标准输入读取的reader
reader := bufio.NewReader(os.Stdin)
fmt.Print("请输入你的名字: ")
name, err := reader.ReadString('\n') // 读取到换行符为止
if err != nil {
fmt.Println("读取输入时出错:", err)
return
}
// 去掉末尾的换行符
name = strings.TrimSpace(name)
fmt.Printf("你好, %s!\n", name)
}
2.2 更实用的输入处理
实际开发中,我们经常需要处理各种类型的输入,比如数字、选择项等:
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// 获取用户年龄
fmt.Print("请输入你的年龄: ")
ageStr, _ := reader.ReadString('\n')
ageStr = strings.TrimSpace(ageStr)
age, err := strconv.Atoi(ageStr) // 转换为整数
if err != nil {
fmt.Println("年龄必须是数字")
return
}
// 根据年龄给出不同回应
if age < 18 {
fmt.Println("你还是个孩子呢")
} else if age < 60 {
fmt.Println("正值壮年啊")
} else {
fmt.Println("人生阅历丰富")
}
// 让用户选择
fmt.Print("你喜欢编程吗?(y/n): ")
choice, _ := reader.ReadString('\n')
choice = strings.ToLower(strings.TrimSpace(choice))
if choice == "y" || choice == "yes" {
fmt.Println("太好了!Go语言是个不错的选择")
} else {
fmt.Println("没关系,每个人都有自己的兴趣")
}
}
3. 综合应用实例
3.1 交互式计算器
把命令行参数和用户输入结合起来,我们可以做一个简单的计算器:
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
// 检查是否有模式参数
mode := "interactive" // 默认交互模式
if len(os.Args) > 1 {
mode = os.Args[1]
}
switch mode {
case "add":
if len(os.Args) < 4 {
fmt.Println("用法: ./calc add <数字1> <数字2>")
return
}
num1, _ := strconv.ParseFloat(os.Args[2], 64)
num2, _ := strconv.ParseFloat(os.Args[3], 64)
fmt.Printf("结果: %.2f\n", num1+num2)
case "interactive":
runInteractiveMode()
default:
fmt.Println("支持的模式: add, interactive")
}
}
func runInteractiveMode() {
reader := bufio.NewReader(os.Stdin)
fmt.Println("=== 简单计算器 ===")
fmt.Println("输入 'quit' 退出程序")
for {
fmt.Print("请输入第一个数字: ")
input1, _ := reader.ReadString('\n')
input1 = strings.TrimSpace(input1)
if input1 == "quit" {
fmt.Println("再见!")
break
}
num1, err := strconv.ParseFloat(input1, 64)
if err != nil {
fmt.Println("请输入有效的数字")
continue
}
fmt.Print("请输入运算符 (+, -, *, /): ")
operator, _ := reader.ReadString('\n')
operator = strings.TrimSpace(operator)
fmt.Print("请输入第二个数字: ")
input2, _ := reader.ReadString('\n')
input2 = strings.TrimSpace(input2)
num2, err := strconv.ParseFloat(input2, 64)
if err != nil {
fmt.Println("请输入有效的数字")
continue
}
var result float64
switch operator {
case "+":
result = num1 + num2
case "-":
result = num1 - num2
case "*":
result = num1 * num2
case "/":
if num2 == 0 {
fmt.Println("除数不能为0")
continue
}
result = num1 / num2
default:
fmt.Println("不支持的运算符")
continue
}
fmt.Printf("结果: %.2f %s %.2f = %.2f\n\n", num1, operator, num2, result)
}
}
4. 编译和使用
4.1 编译程序
Go程序编译很简单,一条命令就搞定:
# 编译当前目录的go文件
go build main.go
# 或者指定输出文件名
go build -o mytool main.go
在Windows下会生成.exe文件,Linux和Mac下是可执行文件。
4.2 运行和测试
编译完成后就可以运行了:
# 不带参数运行
./mytool
# 带参数运行
./mytool add 10 20
# 交互模式
./mytool interactive
5. 两种输入方式的区别
理解os.Args和bufio的区别很重要:
os.Args的特点:
- 程序启动时就确定了,运行过程中不会变
- 适合做程序的配置和模式选择
- 用户必须在启动程序时就提供所有参数
bufio的特点:
- 程序运行时动态获取用户输入
- 可以多次交互,实现对话式程序
- 用户可以根据程序提示逐步输入
实际开发中,这两种方式经常结合使用。用os.Args确定程序的工作模式,用bufio在特定模式下与用户交互。
比如git命令就是这样:git commit确定了要提交代码,如果没有-m参数,git会打开编辑器让你输入提交信息。
掌握了这两个基础工具,你就可以开始写各种实用的命令行程序了。从简单的文件处理工具到复杂的系统管理脚本,都离不开这些基础知识。
- 点赞
- 收藏
- 关注作者
评论(0)