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!") // 显示我们定义的帮助信
													   // 息和默认值
相关推荐
空青72611 分钟前
ChatGPT在Java后端开发中的应用与影响
java·开发语言·人工智能·后端·神经网络·机器学习·chatgpt
搁浅小泽24 分钟前
C 语言总复习
c语言·开发语言
五月阳光暖洋洋33 分钟前
SpringBoot2.2.6使用spring-boot-validation读取不到自定义配置文件中的属性
java·开发语言·spring boot
简单的土拨鼠1 小时前
深入理解go map
go
小悟空GK1 小时前
Http介绍
开发语言
502胶水2051 小时前
腾讯地图异步调用
开发语言·ios·swift
SwBack2 小时前
【pearcmd】通过pearcmd.php 进行GetShell
android·开发语言·php
Lingoesforstudy2 小时前
c#中的超时终止
开发语言·笔记·c#
**K2 小时前
C++ 智能指针使用不当导致内存泄漏问题
开发语言·c++·算法
u0104058362 小时前
如何利用Java Stream API简化集合操作?
java·开发语言