对于程序来说,最本质的就是处理用户的输入和输出。Go生成的可执行文件当然也不例外,我们同样可以让我们的可执行文件拥有处理输入参数的能力。
windows系统中我们经常使用的cmd命令行工具大家很熟悉了,今天我们就模拟下cmd,利用go内置的os包获取一些系统信息。
获取程序输入参数
在Go程序中,程序的命令行参数可从os包的Args变量获取,os包外部使用os.Args访问该变量。首先创建一个新的项目,然后导入os包,然后简单打印下该变量:
package main
import "os"
func main() {
var args = os.Args
for index,element := range args{
println("--------------------------------------------------------------------------------")
println("索引:",index,"| 参数:",element)
}
}
此时运行程序:
os.Args至少有一个元素,该元素代表着命令本身的名称,也就是可执行程序的全路径。注意如果在可执行程序的目录下执行,那么该值就是可执行程序的名称。
当然了我们也可以不用写后缀,直接qos也是可以的:
这样子是不是和我们经常使用的命令行命令没什么区别了呢。不过这样子做是有前提条件的,那就是在系统的环境变量中你已经制定pathext:
如果我们试着去掉exe:
我这里使用的是win10的操作系统,如果大家碰到类似的,可以检查下上面是否包含了你希望运行的文件的后缀。
传递程序参数
传递参数和cmd一样,参数之间以空格作为分隔,至于输入什么看你喜欢了。
下面我们就os包的一些函数做个简单的使用,具体的就不再多说,代码中会有注释。
更多的内容如果大家有兴趣可以自己去看看,毕竟我自己好多都没整明白。。。如果发现哪里有错误的地方希望可以留言提醒下,好让我及时修改,免得给大家错误的例子。
示例代码
package main
import "os"
/*
处理程序参数,这里我们只处理单个参数
示例:
qos hostname
qos filename test.txt
如果没有输入参数,那么提示用户输入必要的参数
*/
// 定义程序可以处理的命令
var cmdArray = [...]string{
//内核提供的主机名
"hostname",
//底层的系统内存页的尺寸
"page",
//环境变量 格式为"key=value"
"environ",
//调用者的用户ID
"uid",
//调用者的有效用户ID
"euid",
//调用者所在进程的进程ID
"pid",
//调用者所在进程的父进程的进程ID
"ppid",
//对应当前工作目录的根路径
"wd",
}
func main() {
// 获取用户输入参数,排除程序名称本身:qos
var paramsCount = len(os.Args) - 1
// 如果参数数量为0,那么提示用户输入参数,并打印可以使用的参数列表
if paramsCount == 0 {
println("请输入您要执行的命令,您可以使用以下命令:")
println("用法:")
println(" qos <command> [arguments]")
println("命令:")
println("\tqos hostname", "\t", "获取内核提供的主机名")
println("\tqos page ", "\t", "获取底层的系统内存页的尺寸")
println("\tqos environ ", "\t", "获取环境变量")
println("\tqos uid ", "\t", "获取调用者的用户ID")
println("\tqos euid ", "\t", "获取调用者的有效用户ID")
println("\tqos pid ", "\t", "获取调用者所在进程的进程ID")
println("\tqos ppid ", "\t", "获取调用者所在进程的父进程的进程ID")
println("\tqos wd ", "\t", "获取对应当前工作目录的根路径")
os.Exit(-1)
}
// 获取输入命令
var command = os.Args[1]
// 根据输入的命令输出对应的结果
switch command {
case "hostname":
var hostname, _ = os.Hostname()
println("hostname:\t", hostname)
case "page":
var page = os.Getpagesize()
println("page:\t", page)
case "environ":
var environ = os.Environ()
for key := range environ {
println(environ[key])
}
case "uid":
var uid = os.Geteuid()
println("uid:\t", uid)
case "euid":
var euid = os.Geteuid()
println("euid:\t", euid)
case "pid":
var pid = os.Getpid()
println("pid:\t", pid)
case "ppid":
var ppid = os.Getppid()
println("ppid:\t", ppid)
case "wd":
var wd, _ = os.Getwd()
println("wd:\t", wd)
default:
println("无法识别参数:", command)
}
}
效果:
使用flag包
package main
import (
"flag"
"os"
)
var (
hostname bool
page bool
environ bool
uid bool
euid bool
pid bool
ppid bool
wd bool
)
func init() {
// 注册flag
flag.BoolVar(&hostname, "hostname", false, "获取内核提供的主机名")
flag.BoolVar(&page, "page", false, "获取底层的系统内存页的尺寸")
flag.BoolVar(&environ, "environ", false, "获取环境变量")
flag.BoolVar(&uid, "uid", false, "获取调用者的用户ID")
flag.BoolVar(&euid, "euid", false, "获取调用者的有效用户ID")
flag.BoolVar(&pid, "pid", false, "获取调用者所在进程的进程ID")
flag.BoolVar(&ppid, "ppid", false, "获取调用者所在进程的父进程的进程ID")
flag.BoolVar(&wd, "wd", false, "获取对应当前工作目录的根路径")
}
/*
处理程序参数,使用flag包
*/
func main() {
// 参数解析,遇到非flag参数停止,可以使用flag.Args()函数获取类似 qflag hostname这样的参数
flag.Parse()
if hostname {
var hostname, _ = os.Hostname()
println("hostname:\t", hostname)
}
if page {
var page = os.Getpagesize()
println("page:\t", page)
}
if environ {
var environ = os.Environ()
for key := range environ {
println(environ[key])
}
}
if uid {
var uid = os.Geteuid()
println("uid:\t", uid)
}
if euid {
var euid = os.Geteuid()
println("euid:\t", euid)
}
if pid {
var pid = os.Getpid()
println("pid:\t", pid)
}
if ppid {
var ppid = os.Getppid()
println("ppid:\t", ppid)
}
if wd {
var wd, _ = os.Getwd()
println("wd:\t", wd)
}
}