44从零开始用Rust编写nginx,命令行参数的设计与解析及说明
wmproxy
wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透,后续将实现websocket代理等,会将实现过程分享出来,感兴趣的可以一起造个轮子
项目地址
国内: https://gitee.com/tickbh/wmproxy
github: https://github.com/tickbh/wmproxy
设计目标
设置启动命令行参数方便在没有配置的情况下启动。
设计事项
当你在Linux终端上输入git --help时,你会看到这样的打印:
shell> git --help
usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
<command> [<args>]
These are common Git commands used in various situations:
start a working area (see also: git help tutorial)
clone Clone a repository into a new directory
init Create an empty Git repository or reinitialize an existing one
...... <omitted>
Git程序支持一长串参数。我们以它为例来讨论程序的参数应该是什么样的。
为了给用户给予一个良好的命令行界面,程序的参数处理部分应该支持以下功能:
- 接受参数的选项
- 不带任何参数的标志/开关
- 长名称(以双连字符开头,如--paginate)和短名称(以单连字符开头,如-p)
- 友好的帮助信息--help
- 子命令(如git add)
通过命令行我们可以执行程序中的非常多的功能,也就是命令行让程序可以在无需GUI的情况下拥有无限丰富的功能。
RUST中的命令行解析
在这里以bpaf来举例,也是本项目中选择的命令行解析库,相对来说他支持宏的同时也支持比较丰富的程序中的组合,也拥有较多的demo可以参考如何使用:
use bpaf::{short, Bpaf, Parser};
use std::path::PathBuf;
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options, version)]
#[allow(dead_code)]
struct Opts {
/// 是否开始调试模式
#[bpaf(short, long)]
debug: bool,
/// 这是一个注释,将被忽略
#[bpaf(external(verbose))]
verbose: usize,
/// 设置速度, 拥有默认速度
#[bpaf(argument("SPEED"), fallback(42.0), display_fallback)]
speed: f64,
/// 输出目录
output: PathBuf,
/// 将检测必须为正数
#[bpaf(guard(positive, "must be positive"), fallback(1))]
nb_cars: u32,
files_to_process: Vec<PathBuf>,
}
fn verbose() -> impl Parser<usize> {
// number of occurrences of the v/verbose flag capped at 3
short('v')
.long("verbose")
.help("启动verbose模式\n根据输入的v的个数来判定等级\n可以 -v -v -v 或者 -vvv")
.req_flag(())
.many()
.map(|xs| xs.len())
.guard(|&x| x <= 3, "最多仅能输入三个v")
}
fn positive(input: &u32) -> bool {
*input > 1
}
fn main() {
println!("{:#?}", opts().run());
}
通过启动打印--help信息可知cargo run --example arg -- --help
PS D:\my\wmproxy> cargo run --example arg -- --help
Compiling wmproxy v0.2.5 (D:\my\wmproxy)
Finished dev [unoptimized + debuginfo] target(s) in 1.12s
Running `target\debug\examples\arg.exe --help`
Usage: arg.exe [-d] [-v]... [--speed=SPEED] --output=ARG [--nb-cars=ARG] [--files-to-process=ARG]...
Available options:
-d, --debug 是否开始调试模式
-v, --verbose 启动verbose模式 根据输入的v的个数来判定等级 可以 -v -v -v 或者 -vvv
--speed=SPEED 设置速度, 拥有默认速度
[default: 42]
--output=ARG 输出目录
--nb-cars=ARG 将检测必须为正数
--files-to-process=ARG
-h, --help Prints help information
-V, --version Prints version information
我们可以通过简单的配置来拥有较完整的命令行的模式的支持,包括默认参数fallback,及完整的help信息。
rust中还有其它较为知名的解析库,图片来源于网上,可根据项目的需要进行相应的选择。

命令行参数
该项目选择用的是子命令的模式
- wmproxy run 启动命令
- wmproxy start 启动命令, 但在后台运行
- wmproxy stop 关闭命令
- wmproxy reload 进行重载配置
- wmproxy check 检查配置是否正确
- wmproxy proxy 代理及内网穿透相关功能
- wmproxy file-server 启动文件服务器
- wmproxy reverse-proxy 启动负载均衡服务器
- wmproxy ws-proxy Websocket协议转发相关
- wmproxy version 打印当前版本号
wmproxy run
通过命令wmproxy run --help可以得到
Usage: wmproxy.exe run -c=ARG [--pidfile=ARG] [--control=ARG] [--disable-stdout] [--disable-control]
[-v] [--default-level=ARG]
Available options:
-c, --config=ARG 配置文件路径
--pidfile=ARG 写入进程id文件
--control=ARG 输入控制台的监听地址
[default: 127.0.0.1:8837]
--disable-stdout 禁用默认输出
--disable-control 禁用控制微端
-v, --verbose 是否显示更多日志
--default-level=ARG 设置默认等级
-h, --help Prints help information
通过配置文件启动程序如:
wmproxy run -c config/reverse.toml
wmproxy start
通过命令wmproxy start --help可以得到
Usage: wmproxy.exe start -c=ARG [--pidfile=ARG] [--control=ARG] [--disable-stdout] [--disable-control]
[-v] [--default-level=ARG]
Available options:
-c, --config=ARG 配置文件路径
--pidfile=ARG 写入进程id文件
--control=ARG 输入控制台的监听地址
[default: 127.0.0.1:8837]
--disable-stdout 禁用默认输出
--disable-control 禁用控制微端
-v, --verbose 是否显示更多日志
--default-level=ARG 设置默认等级
-h, --help Prints help information
通过配置文件启动程序,我们通过观察可以得知参数与run一模一样,差别是该参数将后台启动。
示例如:
wmproxy start -c config/reverse.toml
wmproxy stop
通过命令wmproxy stop --help可以得到
Usage: wmproxy.exe stop [-c=ARG] [-p=ARG] [-u=ARG] [--control=ARG] [--disable-stdout] [--disable-control
] [-v] [--default-level=ARG]
Available options:
-c, --config=ARG 配置文件路径
-p, --pidfile=ARG 写入进程id文件
-u, --url=ARG 控制微端地址
--control=ARG 输入控制台的监听地址
[default: 127.0.0.1:8837]
--disable-stdout 禁用默认输出
--disable-control 禁用控制微端
-v, --verbose 是否显示更多日志
--default-level=ARG 设置默认等级
-h, --help Prints help information
此处我们通过三种方式将其关闭,一种是配置文件,一种是pid文件,一种是控制微端的url。
示例如:
wmproxy stop -c config/reverse.toml
或者
wmproxy stop -p wmproxy.pid
或者
wmproxy stop -u http://127.0.0.1:8837
wmproxy reload
通过命令wmproxy reload --help可以得到
Usage: wmproxy.exe reload [-c=ARG] [-u=ARG] [--control=ARG] [--disable-stdout] [--disable-control] [-v
] [--default-level=ARG]
Available options:
-c, --config=ARG 配置文件路径
-u, --url=ARG 控制微端地址
--control=ARG 输入控制台的监听地址
[default: 127.0.0.1:8837]
--disable-stdout 禁用默认输出
--disable-control 禁用控制微端
此处我们通过三种方式将其重载,一种是配置文件,一种是控制微端的url。
示例如:
wmproxy reload -c config/reverse.toml
或者
wmproxy reload -u http://127.0.0.1:8837
wmproxy proxy
代理类相对参数比较复杂
通过命令wmproxy proxy --help可以得到
Usage: wmproxy.exe proxy [-b=ARG] [--flag=ARG] [--mode=ARG] [-S=ARG] [--user=ARG] [--pass=ARG] [--udp-bind
=ARG] [--map-http-bind=ARG] [--map-https-bind=ARG] [--map-tcp-bind=ARG] [--map-proxy-bind=ARG] [--map-cert
=ARG] [--map-key=ARG] [--center] [--ts] [--tc] [--two-way-tls] [--domain=ARG] [--cert=ARG] [--key=ARG
] [--mappings=ARG]... [--control=ARG] [--disable-stdout] [--disable-control] [-v] [--default-level=ARG
]
代理类, 一个代理类启动一种类型的代理
-b, --bind-addr=ARG 代理绑定端口地址
[default: 127.0.0.1:8090]
--flag=ARG 代理种类, 如http https socks5
--mode=ARG 启动程序类型
-S, --server=ARG 连接代理服务端地址
--user=ARG 用于socks验证及中心服务器验证
--pass=ARG 用于socks验证及中心服务器验证
--udp-bind=ARG udp的绑定地址
--map-http-bind=ARG 内网http的映射地址
--map-https-bind=ARG 内网https的映射地址
--map-tcp-bind=ARG 内网tcp的映射地址
--map-proxy-bind=ARG 内网代理的映射地址
--map-cert=ARG 内网映射的证书cert
--map-key=ARG 内网映射的证书key
--center 是否启用协议转发
--ts 连接服务端是否启用tls
--tc 接收客户端是否启用tls
--two-way-tls 双向认证是否启用
--domain=ARG tls证书所用的域名
--cert=ARG 公开的证书公钥文件
--key=ARG 隐私的证书私钥文件
--mappings=ARG
Available options:
--control=ARG 输入控制台的监听地址
[default: 127.0.0.1:8837]
--disable-stdout 禁用默认输出
--disable-control 禁用控制微端
-v, --verbose 是否显示更多日志
--default-level=ARG 设置默认等级
-h, --help Prints help information
如果仅仅启动代理功能可以
wmproxy proxy -b="127.0.0.1:8090"
或者
wmproxy proxy -b "127.0.0.1:8090"
即可启动8090开始的http/https/socks5代理
wmproxy file-server
启动文件服务
通过命令wmproxy file-server --help可以得到
Usage: wmproxy.exe file-server [-r=ARG] [-l=ARG] [-d=ARG] [-b] [--access-log=ARG] [--control=ARG] [--disable-stdout
] [--disable-control] [-v] [--default-level=ARG]
Available options:
-r, --root=ARG 静态文件根目录路径
-l, --listen=ARG 监听地址
[default: 127.0.0.1:80]
-d, --domain=ARG 域名地址
-b, --browse 是否支持目录
--access-log=ARG 访问日志放的位置如"logs/access.log trace"
--control=ARG 输入控制台的监听地址
[default: 127.0.0.1:8837]
--disable-stdout 禁用默认输出
--disable-control 禁用控制微端
-v, --verbose 是否显示更多日志
--default-level=ARG 设置默认等级
-h, --help Prints help information
如果仅仅启动代理功能可以
wmproxy file-server
或者
wmproxy file-server -l :8080 -r "d:/my/wmproxy"
即可启动文件服务器对其服务。
wmproxy reverse-proxy
启动负载均衡服务
通过命令wmproxy reverse-proxy --help可以得到
Usage: wmproxy.exe reverse-proxy [-f=ARG] -t=ARG [-H=ARG]... [--access-log=ARG] [--tls] [--control=ARG
] [--disable-stdout] [--disable-control] [-v] [--default-level=ARG]
Available options:
-f, --from=ARG 负载均衡来源地址
[default: 127.0.0.1:80]
-t, --to=ARG 负载均衡映射地址
-H, --header=ARG 头部信息修改如 "proxy x-forward-for {client_ip}"
--access-log=ARG 访问日志放的位置如"logs/access.log trace"
--tls 是否映射到https上
--control=ARG 输入控制台的监听地址
[default: 127.0.0.1:8837]
--disable-stdout 禁用默认输出
--disable-control 禁用控制微端
-v, --verbose 是否显示更多日志
--default-level=ARG 设置默认等级
-h, --help Prints help information
需要配置从源目标到目标的信息,可以配置header等相应的信息。
wmproxy reverse-proxy
或者
wmproxy reverse-proxy -t :8080
即可启动负载均衡服务对其服务。
wmproxy ws-proxy
启动websocket协议转发服务
通过命令wmproxy ws-proxy --help可以得到
Usage: wmproxy.exe ws-proxy [-f=ARG] -t=ARG [--access-log=ARG] --mode=<ws2tcp,tcp2ws,tcp2wss> [--ws]
[--control=ARG] [--disable-stdout] [--disable-control] [-v] [--default-level=ARG]
Available options:
-f, --from=ARG 负载均衡来源地址
[default: 127.0.0.1:80]
-t, --to=ARG 负载均衡映射地址
--access-log=ARG 访问日志放的位置如"logs/access.log trace"
--mode=<ws2tcp,tcp2ws,tcp2wss> 当前代理的模式
--domain=ARG 当前域名
--ws 是否支持websocket
--control=ARG 输入控制台的监听地址
[default: 127.0.0.1:8837]
模式中
- ws2tcp 指websocket的流量转成tcp
- tcp2ws 指tcp的流量转成websocket
- tcp2wss 指tcp的流量转成websocket tls流量
# 将流量通过ws转成tcp
wmproxy ws-proxy -t :8082 --mode ws2tcp
或者
# 将流量通过tcp转成ws
wmproxy ws-proxy -t :8099 --mode tcp2ws
即可启动websocket的流量。
wmproxy version
打印当前软件的版本号
小结
好的命令行可以执行更强大的功能,也能让人更好的理解你的程序,这需要有一个好的帮助系统,也需要有一个强大的解析能力。此章讲述了命令行的执行功能,希望可以帮助到你的使用。
点击 [关注],[在看],[点赞] 是对作者最大的支持
44从零开始用Rust编写nginx,命令行参数的设计与解析及说明的更多相关文章
- nginx命令行参数和信号
nginx命令行参数 [user@host dir]$ /usr/local/nginx/sbin/nginx -hnginx version: nginx/1.8.0Usage: nginx [-? ...
- nginx命令行参数
通过控制台进入nginx目录后 1. 启动nginx start nginx 或 nginx.exe 2. 重启nginx nginx -s reload 3. 停止nginx nginx -s st ...
- 运行和控制Nginx——命令行参数和信号
参考资料: Nginx中文文档: http://www.nginx.cn/nginxchscommandline Nginx的启动.停止.平滑重启.信号控制和平滑升级:http://zachary-g ...
- nginx 命令行参数 启动 重启 重载 停止
今天和大家分享关于 nginx 的一些参数使用 首先,你应该安装了nginx CentOS 安装 nginx 这是很早之前的一篇博客,可以参考. 之前,我们如何去操作 nginx ##简单粗暴法 pk ...
- C语言中使用库函数解析命令行参数
在编写需要命令行参数的C程序的时候,往往我们需要先解析命令行参数,然后根据这些参数来启动我们的程序. C的库函数中提供了两个函数可以用来帮助我们解析命令行参数:getopt.getopt_long. ...
- 如何编写一个带命令行参数的Python文件
看到别人执行一个带命令行参数的python文件,瞬间觉得高大上起来.牛逼起来,那么如何编写一个带命令行参数的python脚本呢?不用紧张,下面将简单易懂地让你学会如何让自己的python脚本,支持带命 ...
- Nginx命令行控制
在Linux中,需要使用命令行来控制Nginx服务器的启动与停止.重载配置文件.回滚日志文件.平滑升级等行为.默认情况下,Nginx被安装在目录usrlocal/nginx/中,其二进制文件路径为us ...
- nginx 支持的命令行参数
Command-line parameters 命令行参数 nginx supports the following command-line parameters: nginx支持以下命令行参数 - ...
- 让你如绅士般基于描述编写 Python 命令行工具的开源项目:docopt
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- nginx使用手册--nginx的命令行参数
nginx的命令行参数 -? 或者 -h 打印命令行参数帮助信息 -c file 为 Nginx 指定一个配置文件,来代替缺省的. -t 不运行,而仅仅测试配置文件.nginx 将检查配置文件的语法的 ...
随机推荐
- 在IDEA启动多个Spring Boot工程实例
在IDEA上点击Application右边的下三角 ,弹出选项后,点击Edit Configuration 选中需要多实例启动的应用,将默认的Single instance only(单实例)的钩去掉 ...
- 『Flutter』开发环境搭建
1.前言 大家好,我是 BNTang,今天给大家介绍一下 Flutter 的开发环境搭建.在之前我已经将 Dart 的基本语法给大家介绍了,所以今天就不再介绍 Dart 的基本语法了,直接进入 Flu ...
- Eureka:Spring Cloud服务注册和发现组件
Eureka:Spring Cloud服务注册和发现组件 问题总结 Eureka 两大组件? Eureka 服务注册与发现? Eureka Server 集群? Eureka 自我保护机制? 问题答案 ...
- Redis 打怪升级进阶成神之路(2023 最新版)!
前面我们学习:MySQL 打怪升级进阶成神之路(2023 最新版)!,然后我们就开始了 NoSQL 卷王之路.从第一篇文章开始,我们逐步详细介绍了 Redis 基础理论与安装配置.9 种数据类型和应用 ...
- Linux 逻辑卷管理
如果用标准分区在硬盘上创建了文件系统,为已有的文件系统添加额外的空间是一件十分痛苦的事情.只能在已有的硬盘上的可用空间范围内调整分区大小,如果硬盘空间不够的话,就只能换一个大容量的硬盘,然后手动将已有 ...
- 2023-08-26:请用go语言编写。开心一下的智力题: 有一个村庄,一共250人, 每一个村民要么一定说谎,要么只说真话, 村里有A、B、C、D四个球队,且每个村民只会喜欢其中的一支球队, 但是说
2023-08-26:请用go语言编写.开心一下的智力题: 有一个村庄,一共250人, 每一个村民要么一定说谎,要么只说真话, 村里有A.B.C.D四个球队,且每个村民只会喜欢其中的一支球队, 但是说 ...
- Java PDF文档转换 — PDF转Excel、SVG转PDF
概述 Spire.PDF for Java支持将PDF文档高质量地转换为XPS.图片.SVG.Word.HTML和PDF/A格式,以及支持将XPS.HTML文档转换为PDF格式.本文将通过代码演示来介 ...
- GaussDB(DWS)集群中寻找节点CPU占用高的语句
摘要:本文主要通过实例讲解如何通过gs_cpuwatcher.sh 脚本寻找CPU占用高语句. 本文分享自华为云社区<GaussDB(DWS) gs_cpuwatcher.sh 脚本如何寻找CP ...
- 震惊,PostGIS还可以这样用!!!
摘要:PostGIS为PostgreSQL提供了空间数据库分析能力,是目前业界主流的地理数据库之一,提供如下空间信息服务功能:空间对象.空间索引.空间操作函数和空间操作符等.在GaussDB 中,目前 ...
- iOS上架报错:无法添加以供审核
无法提交以供审核 要开始审核流程 必须提供以下项目 您必须为要添加的 app 提供版权信息. 您在提交 app 审核时遇到的问题是因为需要提供版权信息,而您的 app 缺少相关的版权信息.以下是解 ...