17.1 命令行-输入与输出、命令行参数、命令行标志

1. 输入与输出

命令行程序被设计为在终端运行。在图形用户界面(GUI)问世以前的年代,命令行程序是与计算机交互的唯一方式。

即便是在图形用户界面大行其道的当今,对程序员和系统管理员来说,命令行程序依然是一种流行而实用的与底层操作系统交互的工具。

命令行程序通常执行这样的操作:接受用户输入的数据,打印一些输出结果。

命令行程序可用任何语言编写,只要它是可执行的,就可以在终端中运行它:

  • 以交互的方式运行
  • 以批量的方式运行:脚本程序
  • 按照定时自动运行
  • 操作系统后台运行:随系统启动而启动,在后台静默运行

命令行程序与外界交互的界面就是终端。终端的I/O通道包括标准输入、标准输出和标准错误。

|------|----|----------------|
| 名称 | 代码 | 描述 |
| 标准输入 | 0 | 程序读取数据的来源,默认键盘 |
| 标准输出 | 1 | 程序写入数据的目标,默认屏幕 |
| 标准错误 | 2 | 程序报告错误的目标,默认屏幕 |

标准输入、标准输出和标准错误都有默认设备与之关联,但借助操作系统的I/O重定向,也可将其关联到其它设备,比如磁盘文件。

  • cat 0<in 1>out 2>err // 分别将标准输入,标准输出和标准错误重定向至in, out, err文件,0,1,2为三者的标准设备代码。其中,标准输入与标准输出的标准设备代码可缺省。
  • cat <in >>out 2>>err // >表示更新文件中的内容;>>表示在保留原文件内容的前提下,更新文件中的内容;
  • cat <in >>out 2>>&1 // 可以引用标准设备代码,&1,在此表示,将标准错误重定向至"标准输出"文件。

2. 命令行参数

命令行程序可以通过命令行参数接收用户的输入数据。

  • main.exe windows macos linux

标准库os包里的导出变量Args是一个字符串切片,其中保存了命令行程序的文件路径和传递给命令行程序的每一个参数。

  • os.Args:
    • +----------+---------+-------+-------+
    • | main.exe | windows | macos | linux |
    • +----------+---------+-------+-------+
    • 0 1 2 3

遍历命令行程序文件路径和每一个命令行参数。

  • for _, arg := range os.Args { ... }
Go 复制代码
// 访问命令行参数
// 要读取命令行程序的参数,可使用标准库的os包
package main

import (
    "fmt"
    "os"
)

func main() {
    for i, arg := range os.Args {
        fmt.Println(i, arg)
    }
}
// 打印输出:
PS G:\GoWorkspace\src\cli\args> ./main.exe windows macos linux 
 0 G:\GoWorkspace\src\cli\args\main.exe
 1 windows
 2 macos 
 3 linux 

3.命令行标志

命令行参数通常包含多个标志,每个标志由标志名和可选的标志值组成.

  • 如果用户所提供的命令行参数中没有包含某个标志,则其标志值取默认值。
  • main.exe -name Susan -age 30 -female -female没有给出标准值,采用默认值

如果用户所提供的命令行参数不正确或使用了帮助标志,则显示帮助信息。

Usage of main.exe:

-age int

Your age (default 20)

-female

You are female

-name string

Your name (default "Anonymous")

标准库中的flag包提供了比os包更多用于解析命令行参数的功能。

  • 指定标志的数据类型
  • 设置标志的默认取值
  • 生成标志的帮助信息

例如:为了从命令行标志中获取名为s的string型标志值。

s := flag.String("s", "Hello World!", "Greeting message")

// flag.String()返回值s为string型指针

flag.Parse() // 解析命令行,s指向命令行参数中的参数值golang

fmt.Println(*s) // golang,s是一个指针,指向标志名为s的标志值

main.exe -s golang

Go 复制代码
// 解析命令行标志
// 借助标准库的flag包解析命令行标志 
// 标志指针 = flag.String(标志名, 默认值, 帮助文本) 
// flag.Parse() 
// 命令 -标志名 标志值[默认值] 
//            	   ^ 
//            	   | 
//	           标志指针
package main
import (
    "flag"
    "fmt"
)
func main() {
    s := flag.String("s", "Hello World!",
        "Greeting message")
    flag.Parse()
    fmt.Println(*s)
}
// 打印输出:
 PS G:\GoWorkspace\src\cli\flag> ./main.exe -s golang // 我们输入
 golang // 程序的输出,成功解析命令行标志值

 PS G:\GoWorkspace\src\cli\flag> ./main.exe -h // 我们输入
 Usage of G:\GoWorkspace\src\cli\flag\main.exe:	// -h打印帮助信息
   -s string
         Greeting message (default "Hello World!") // 显示我们定义的帮助信
													   // 息和默认值
相关推荐
杨荧35 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
白子寰42 分钟前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
王俊山IT1 小时前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
为将者,自当识天晓地。1 小时前
c++多线程
java·开发语言
小政爱学习!1 小时前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
神奇夜光杯1 小时前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
Themberfue1 小时前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
plmm烟酒僧1 小时前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
测试界的酸菜鱼2 小时前
Python 大数据展示屏实例
大数据·开发语言·python