命令行解析函数:getopt_long、getopt
一、前言
在学习一些项目代码时,尤其涉及到命令行传参的代码,经常遇到getopt相关的函数,对这一类函数可以说是既陌生又熟悉。陌生是因为不知道它是干啥的,熟悉呢,是因为经常遇到。于是乎在追踪了多天ipsec配置文件解析流程之后,准备学习下这一类命令行解析利器。
这么多命令行参数,需要解析,想象都让人头大,如果再没有一个好的解析方式,那就雪上加霜了。辛亏有了一类命令行解析函数,可以让这些解析操作变得容易一点点。下面就简单的介绍下这一类函数,主要有getopt、getopt_long、getopt_long_only。
Man 手册信息如下:
NAME
getopt, getopt_long, getopt_long_only, optarg, optind, opterr, optopt - Parse command-line options
SYNOPSIS
#include <unistd.h>
int getopt(int argc, char * const argv[],
const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
#include <getopt.h>
int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
先从最简单的,最基本的getopt函数开始。然后再介绍增强版的getopt_long函数。
二、getopt函数
2.1 函数简介:
int getopt(int argc, char * const argv[], const char *optstring); |
各项参数解释如下:
函数功能 |
用来解析命令行选项参数,只适用于短选项:-d /root; 不能解析长选项--arch, --help等 |
Argc |
通过命令行传给main函数参数的个数 |
argv |
通过命令行传给main函数参数组成的字符串指针数组 |
optstring |
选项字符串。用来告诉getopt可以解析哪些选项,哪些选项需要参数以及函数返回值等(字符后面紧跟一个冒号则需要参数,而两个则表示参数可选) |
返回值 |
如果成功返回选项字母;命令行解析完毕返回-1;如果选项未定义,则提示错误信息,并返回'?';如果参数缺失,第一个字符是':'则返回':', 否则返回'?' |
对于optstring字符串格式做一个简单说明:
单个字符,表示没有参数 单个字符紧跟1个冒号,表示必须有参数,格式:-d xxx或者-dxxx 单个字符紧跟2个冒号,表示参数可选,格式:-dxxx |
Char *optstring="ab:c::"; 说明:此选项指定了三个选项,分别为'a'、'b'、'c'。其中 a选项无需参数,格式:-a即可 b选项必须有参数,格式:-d xxx c选项参数可选,格式:-c ooo |
在此类函数中,需要几个重要的变量共同配合才能完成命令行参数解析工作:
变量名称 |
作用 |
Char *optarg |
指向当前选项参数的指针 |
Int optind |
用来记录当前已遍历选项的索引,方便下次调用时直接找到下一个选项 |
Int opterr |
正常情况,解析失败会有错误信息,如果不需要此错误信息,将opterr置0即可 |
Int optopt |
最后一个未知选项 |
2.2 举例说明:
代码如下:
/*************************************************************************
> File Name: getopt.c
> Author: Toney
> Mail: vip_13031075266@163.com
> Created Time: 2021年01月30日 星期六 21时50分45秒
************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
void main(int argc, char **argv)
{
int flags, opt;
while((opt = getopt(argc, argv, "ab:c::")) != -1){
switch(opt){
case 'a':
printf("Input %d parameter is -a=%s\n", optind, optarg);
break;
case 'b':
printf("Input %d parameter is -b=%s\n", optind, optarg);
break;
case 'c':
printf("Input %d parameter is -c=%s\n", optind, optarg);
break;
default:
printf("Not match!!!");
}
}
return ;
}
三、getopt_long函数
3.1 函数简介:
int getopt_long(int argc, char * const argv[], const char *optstring,const struct option *longopts, int *longindex); |
各项参数解释如下:
函数功能 |
用来解析命令行选项参数,除了getopt函数支持的短选项,还支持长选项,如--help, --prefix |
Argc |
通过命令行传给main函数参数的个数 |
argv |
通过命令行传给main函数参数组成的字符串指针数组 |
optstring |
选项字符串。用来告诉getopt可以解析哪些选项,哪些选项需要参数以及函数返回值等(字符后面紧跟一个冒号则需要参数,而两个则表示参数可选) |
longopts |
长选项参数的名称、属性、以及解析后的返回值等结构信息 |
longindex |
用来记录解析到的当前长选项的索引,也就是longopts的下标。 |
返回值 |
对于短选项,返回值同getopt函数;对于长选项,如果flag是NULL,返回val,否则返回0;对于错误情况返回值同getopt函数 |
Struct option结构体:
struct option { |
其中has_arg类型取值有如下几种:
No_argument |
不需要参数 |
Required_argument |
必须带参数 |
Optional_argument |
参数可选 |
在此类函数中,需要几个重要的变量共同配合才能完成命令行参数解析工作:
变量名称 |
作用 |
Char *optarg |
指向当前选项参数的指针 |
Int optind |
用来记录当前已遍历选项的索引,方便下次调用时直接找到下一个选项 |
Int opterr |
正常情况,解析失败会有错误信息,如果不需要此错误信息,将opterr置0即可 |
Int optopt |
最后一个未知选项 |
3.2 ipsec项目中的一个例子:
先看看在openswan源码中,有关使用getopt_long解析命令行的一个例子(各位把住坐稳了):
static const struct option long_opts[] = {
# define OO OPTION_OFFSET
/* name, has_arg, flag, val */
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ "optionsfrom", required_argument, NULL, '+' },
{ "label", required_argument, NULL, 'l' },
{ "ctlbase", required_argument, NULL, OPT_CTLBASE + OO },
{ "name", required_argument, NULL, OPT_NAME + OO },
{ "connalias", required_argument, NULL, OPT_CONNALIAS + OO },
{ "keyid", required_argument, NULL, OPT_KEYID + OO },
{ "addkey", no_argument, NULL, OPT_ADDKEY + OO },
{ "pubkeyrsa", required_argument, NULL, OPT_PUBKEYRSA + OO },
{ "myid", required_argument, NULL, OPT_MYID + OO },
{ "route", no_argument, NULL, OPT_ROUTE + OO },
{ "unroute", no_argument, NULL, OPT_UNROUTE + OO },
{ "initiate", no_argument, NULL, OPT_INITIATE + OO },
{ "terminate", no_argument, NULL, OPT_TERMINATE + OO },
{ "delete", no_argument, NULL, OPT_DELETE + OO },
{ "deletestate", required_argument, NULL, OPT_DELETESTATE + OO + NUMERIC_ARG },
{ "crash", required_argument, NULL, OPT_DELETECRASH + OO },
{ "listen", no_argument, NULL, OPT_LISTEN + OO },
{ "unlisten", no_argument, NULL, OPT_UNLISTEN + OO },
{ "purgeocsp", no_argument, NULL, OPT_PURGEOCSP + OO },
{ "rereadsecrets", no_argument, NULL, OPT_REREADSECRETS + OO },
{ "rereadcacerts", no_argument, NULL, OPT_REREADCACERTS + OO },
{ "rereadaacerts", no_argument, NULL, OPT_REREADAACERTS + OO },
{ "rereadocspcerts", no_argument, NULL, OPT_REREADOCSPCERTS + OO },
{ "rereadacerts", no_argument, NULL, OPT_REREADACERTS + OO },
{ "rereadcrls", no_argument, NULL, OPT_REREADCRLS + OO },
{ "rereadall", no_argument, NULL, OPT_REREADALL + OO },
{ "status", no_argument, NULL, OPT_STATUS + OO },
{ "shutdown", no_argument, NULL, OPT_SHUTDOWN + OO },
{ "xauthname", required_argument, NULL, OPT_XAUTHNAME + OO },
{ "xauthuser", required_argument, NULL, OPT_XAUTHNAME + OO },
{ "xauthpass", required_argument, NULL, OPT_XAUTHPASS + OO },
{ "tpmeval", required_argument, NULL, OPT_TPMEVAL + OO },
{ "oppohere", required_argument, NULL, OPT_OPPO_HERE + OO },
{ "oppothere", required_argument, NULL, OPT_OPPO_THERE + OO },
{ "asynchronous", no_argument, NULL, OPT_ASYNC + OO },
/* list options */
{ "utc", no_argument, NULL, LST_UTC + OO },
{ "checkpubkeys", no_argument, NULL, LST_CHECKPUBKEYS + OO },
{ "listpubkeys", no_argument, NULL, LST_PUBKEYS + OO },
{ "listcerts", no_argument, NULL, LST_CERTS + OO },
{ "listcacerts", no_argument, NULL, LST_CACERTS + OO },
{ "listacerts", no_argument, NULL, LST_ACERTS + OO },
{ "listaacerts", no_argument, NULL, LST_AACERTS + OO },
{ "listocspcerts", no_argument, NULL, LST_OCSPCERTS + OO },
{ "listgroups", no_argument, NULL, LST_GROUPS + OO },
{ "listcrls", no_argument, NULL, LST_CRLS + OO },
{ "listocsp", no_argument, NULL, LST_OCSP + OO },
{ "listpsks", no_argument, NULL, LST_PSKS + OO },
{ "listevents", no_argument, NULL, LST_EVENTS + OO },
{ "listpairs", no_argument, NULL, LST_HOSTPAIRS + OO },
{ "listhostpairs", no_argument, NULL, LST_HOSTPAIRS + OO },
{ "listall", no_argument, NULL, LST_ALL + OO },
/* options for an end description */
{ "host", required_argument, NULL, END_HOST + OO },
{ "id", required_argument, NULL, END_ID + OO },
{ "cert", required_argument, NULL, END_CERT + OO },
{ "ca", required_argument, NULL, END_CA + OO },
{ "groups", required_argument, NULL, END_GROUPS + OO },
{ "ikeport", required_argument, NULL, END_IKEPORT + OO + NUMERIC_ARG },
{ "nexthop", required_argument, NULL, END_NEXTHOP + OO },
{ "client", required_argument, NULL, END_CLIENT + OO },
{ "clientwithin", required_argument, NULL, END_CLIENTWITHIN + OO },
{ "clientprotoport", required_argument, NULL, END_CLIENTPROTOPORT + OO },
{ "dnskeyondemand", no_argument, NULL, END_DNSKEYONDEMAND + OO },
{ "srcip", required_argument, NULL, END_SRCIP + OO },
{ "updown", required_argument, NULL, END_UPDOWN + OO },
{ "tundev", required_argument, NULL, END_TUNDEV + OO + NUMERIC_ARG },
/* options for a connection description */
{ "to", no_argument, NULL, CD_TO + OO },
{ "psk", no_argument, NULL, CD_PSK + OO },
{ "rsasig", no_argument, NULL, CD_RSASIG + OO },
{ "encrypt", no_argument, NULL, CD_ENCRYPT + OO },
{ "authenticate", no_argument, NULL, CD_AUTHENTICATE + OO },
{ "compress", no_argument, NULL, CD_COMPRESS + OO },
{ "overlapip", no_argument, NULL, CD_OVERLAPIP + OO },
{ "tunnel", no_argument, NULL, CD_TUNNEL + OO },
{ "tunnelipv4", no_argument, NULL, CD_TUNNELIPV4 + OO },
{ "tunnelipv6", no_argument, NULL, CD_TUNNELIPV6 + OO },
{ "pfs", no_argument, NULL, CD_PFS + OO },
{ "sha2_truncbug", no_argument, NULL, CD_SHA2_TRUNCBUG + OO },
{ "aggrmode", no_argument, NULL, CD_AGGRESSIVE + OO },
{ "disablearrivalcheck", no_argument, NULL, CD_DISABLEARRIVALCHECK + OO },
{ "initiateontraffic", no_argument, NULL
, CD_SHUNT0 + (POLICY_SHUNT_TRAP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
{ "pass", no_argument, NULL
, CD_SHUNT0 + (POLICY_SHUNT_PASS >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
{ "drop", no_argument, NULL
, CD_SHUNT0 + (POLICY_SHUNT_DROP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
{ "reject", no_argument, NULL
, CD_SHUNT0 + (POLICY_SHUNT_REJECT >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
{ "failnone", no_argument, NULL
, CD_FAIL0 + (POLICY_FAIL_NONE >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
{ "failpass", no_argument, NULL
, CD_FAIL0 + (POLICY_FAIL_PASS >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
{ "faildrop", no_argument, NULL
, CD_FAIL0 + (POLICY_FAIL_DROP >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
{ "failreject", no_argument, NULL
, CD_FAIL0 + (POLICY_FAIL_REJECT >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
{ "dontrekey", no_argument, NULL, CD_DONT_REKEY + OO },
{ "forceencaps", no_argument, NULL, CD_FORCEENCAPS + OO },
{ "dpddelay", required_argument, NULL, CD_DPDDELAY + OO + NUMERIC_ARG },
{ "dpdtimeout", required_argument, NULL, CD_DPDTIMEOUT + OO + NUMERIC_ARG },
{ "dpdaction", required_argument, NULL, CD_DPDACTION + OO },
#ifdef XAUTH
{ "xauth", no_argument, NULL, END_XAUTHSERVER + OO },
{ "xauthserver", no_argument, NULL, END_XAUTHSERVER + OO },
{ "xauthclient", no_argument, NULL, END_XAUTHCLIENT + OO },
#endif
#ifdef MODECFG
{ "modecfgpull", no_argument, NULL, CD_MODECFGPULL + OO },
{ "modecfgserver", no_argument, NULL, END_MODECFGSERVER + OO },
{ "modecfgclient", no_argument, NULL, END_MODECFGCLIENT + OO },
#ifdef MODECFG_DNSWINS
{ "modecfgdns1", required_argument, NULL, CD_MODECFGDNS1 + OO },
{ "modecfgdns2", required_argument, NULL, CD_MODECFGDNS2 + OO },
{ "modecfgwins1", required_argument, NULL, CD_MODECFGWINS1 + OO },
{ "modecfgwins2", required_argument, NULL, CD_MODECFGWINS2 + OO },
{ "modeconfigserver", no_argument, NULL, END_MODECFGSERVER + OO },
{ "modeconfigclient", no_argument, NULL, END_MODECFGCLIENT + OO },
#endif
#endif
{ "metric", required_argument, NULL, CD_METRIC + OO + NUMERIC_ARG },
{ "mtu", required_argument, NULL, CD_CONNMTU + OO + NUMERIC_ARG },
{ "sendcert", required_argument, NULL, END_SENDCERT + OO },
{ "certtype", required_argument, NULL, END_CERTTYPE + OO + NUMERIC_ARG },
{ "ipv4", no_argument, NULL, CD_CONNIPV4 + OO },
{ "ipv6", no_argument, NULL, CD_CONNIPV6 + OO },
{ "ikelifetime", required_argument, NULL, CD_IKELIFETIME + OO + NUMERIC_ARG },
{ "ipseclifetime", required_argument, NULL, CD_IPSECLIFETIME + OO + NUMERIC_ARG },
{ "rekeymargin", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG },
{ "rekeywindow", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG }, /* OBSOLETE */
{ "rekeyfuzz", required_argument, NULL, CD_RKFUZZ + OO + NUMERIC_ARG },
{ "keyingtries", required_argument, NULL, CD_KTRIES + OO + NUMERIC_ARG },
{ "ike", required_argument, NULL, CD_IKE + OO },
{ "ikealg", required_argument, NULL, CD_IKE + OO },
{ "pfsgroup", required_argument, NULL, CD_PFSGROUP + OO },
{ "esp", required_argument, NULL, CD_ESP + OO },
{ "remote_peer_type", required_argument, NULL, CD_REMOTEPEERTYPE + OO},
#ifdef HAVE_NM
{ "nm_configured", no_argument, NULL, CD_NMCONFIGURED + OO},
#endif
#ifdef HAVE_LABELED_IPSEC
{ "loopback", no_argument, NULL, CD_LOOPBACK + OO},
{ "labeledipsec", no_argument, NULL, CD_LABELED_IPSEC + OO},
{ "policylabel", required_argument, NULL, CD_POLICY_LABEL + OO },
#endif
#ifdef DEBUG
{ "debug-none", no_argument, NULL, DBGOPT_NONE + OO },
{ "debug-all", no_argument, NULL, DBGOPT_ALL + OO },
{ "debug-raw", no_argument, NULL, DBGOPT_RAW + OO },
{ "debug-crypt", no_argument, NULL, DBGOPT_CRYPT + OO },
{ "debug-parsing", no_argument, NULL, DBGOPT_PARSING + OO },
{ "debug-emitting", no_argument, NULL, DBGOPT_EMITTING + OO },
{ "debug-control", no_argument, NULL, DBGOPT_CONTROL + OO },
{ "debug-lifecycle", no_argument, NULL, DBGOPT_LIFECYCLE + OO },
{ "debug-klips", no_argument, NULL, DBGOPT_KLIPS + OO },
{ "debug-netkey", no_argument, NULL, DBGOPT_KLIPS + OO },
{ "debug-xfrm", no_argument, NULL, DBGOPT_KLIPS + OO },
{ "debug-dns", no_argument, NULL, DBGOPT_DNS + OO },
{ "debug-oppo", no_argument, NULL, DBGOPT_OPPO + OO },
{ "debug-oppoinfo", no_argument, NULL, DBGOPT_OPPOINFO + OO },
{ "debug-whackwatch", no_argument, NULL, DBGOPT_WHACKWATCH + OO },
{ "debug-controlmore", no_argument, NULL, DBGOPT_CONTROLMORE + OO },
{ "debug-pfkey", no_argument, NULL, DBGOPT_PFKEY + OO },
{ "debug-nattraversal", no_argument, NULL, DBGOPT_NATT + OO },
{ "debug-natt", no_argument, NULL, DBGOPT_NATT + OO },
{ "debug-nat_t", no_argument, NULL, DBGOPT_NATT + OO },
{ "debug-nat-t", no_argument, NULL, DBGOPT_NATT + OO },
{ "debug-x509", no_argument, NULL, DBGOPT_X509 + OO },
{ "debug-dpd", no_argument, NULL, DBGOPT_DPD + OO },
{ "debug-private", no_argument, NULL, DBGOPT_PRIVATE + OO },
{ "impair-delay-adns-key-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER + OO },
{ "impair-delay-adns-txt-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER + OO },
{ "impair-bust-mi2", no_argument, NULL, DBGOPT_IMPAIR_BUST_MI2 + OO },
{ "impair-bust-mr2", no_argument, NULL, DBGOPT_IMPAIR_BUST_MR2 + OO },
{ "impair-sa-fail", no_argument, NULL, DBGOPT_IMPAIR_SA_CREATION + OO },
{ "impair-die-oninfo", no_argument, NULL, DBGOPT_IMPAIR_DIE_ONINFO + OO },
{ "impair-jacob-two-two", no_argument, NULL, DBGOPT_IMPAIR_JACOB_TWO_TWO + OO },
{ "impair-major-version-bump", no_argument, NULL, DBGOPT_IMPAIR_MAJOR_VERSION_BUMP + OO },
{ "impair-minor-version-bump", no_argument, NULL, DBGOPT_IMPAIR_MINOR_VERSION_BUMP + OO },
{ "impair-retransmits", no_argument, NULL, DBGOPT_IMPAIR_RETRANSMITS + OO },
{ "impair-send-bogus-isakmp-flag", no_argument, NULL, DBGOPT_IMPAIR_SEND_BOGUS_ISAKMP_FLAG + OO },
{ "whackrecord", required_argument, NULL, OPT_WHACKRECORD + OO},
{ "whackstoprecord", no_argument, NULL, OPT_WHACKSTOPRECORD + OO},
#endif
# undef OO
{ 0,0,0,0 }
};
这是whack命令解析时的一个结构信息,可以想象它的配置命令是有多少,而具体实现差不多800行左右的C代码。这里需要注意的是:struct option结构中的val取值通常是单个字符或者数字。由于单字符数量有限,参数比较少时可以使用字符,但是如果像上面辣么多参数,通常采用枚举类型,方便扩展。
四、getopt_long_only函数
getopt_long_only 函数与 getopt_long 函数使用相同的参数表,在功能上基本一致,只是 getopt_long 只将 --name 当作长参数,但 getopt_long_only 会将 --name 和 -name 两种选项都当作长参数来匹配。getopt_long_only 如果选项 -name 不能在 longopts 中匹配,但能匹配一个短选项,它就会解析为短选项。
命令行解析函数:getopt_long、getopt的更多相关文章
- C语言命令行解析函数:getopt/getopt_long
命令行工具下的参数选项有两种,长选项和短选项.短选项以-开头,后面跟单个字母:长选项以--开头,后面可跟多个字母. 一. getopt() 1.功能:解析命令行短选项参数 2.函数原型: #inclu ...
- 命令行解析函数:getopt/getopt_long
参考: http://blog.csdn.net/zhangyang0402/article/details/5671410 http://www.cnblogs.com/gnuhpc/archive ...
- 【C】命令行参数解析——getopt、getopt_long及getopt_long_only
前言 在linux下学习开源代码Webbench,遇到get_long等函数的用法,一时有点懵,故想深入了解这类命令行解析函数,并记此博文. 1.getopt getopt主要用来处理短命令行选项,例 ...
- [转]Python 命令行参数和getopt模块详解
FROM : http://www.tuicool.com/articles/jaqQvq 有时候我们需要写一些脚本处理一些任务,这时候往往需要提供一些命令行参数,根据不同参数进行不同的处理,在Pyt ...
- Python 命令行参数和getopt模块详解
有时候我们需要写一些脚本处理一些任务,这时候往往需要提供一些命令行参数,根据不同参数进行不同的处理,在Python里,命令行的参数和C语言很类似(因为标准Python是用C语言实现的).在C语言里,m ...
- linux 中解析命令行参数(getopt_long用法)
linux 中解析命令行参数(getopt_long用法) http://www.educity.cn/linux/518242.html 详细解析命令行的getopt_long()函数 http:/ ...
- shell 命令行参数(getopt和getopts)
getopt 命令 使用getopt命令,可以解析任何命令行选项和参数,但是用法比较复杂.getopt的命令用法如下: $ getopt --help 用法: getopt optstring par ...
- 命令行参数处理-getopt()和getopt_long()
在实际编程当中,自己编写代码处理命令行参数是比较麻烦且易出错的.一般我们会直接使用getopt()和getopt_long()函数,下文将介绍具体的使用方法. getopt() getopt()用于处 ...
- 命令行解析getopt_long
getopt_long函数可以轻松的解析main函数的命令行参数. int getopt_long(int argc,char * const argv[],const char *optstring ...
随机推荐
- 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件 内容简介:本文介绍 Spring Boot 的配置文件和配置管理,以及介绍了三种读取配置文 ...
- shell中cmd1 && cmd2 || cmd3的含义
在某些情况下,很多指令我想要一次输入去执行,而不想要分次去执行时,就要用到 && || 了.cmd 1 && cmd21,若cmd1执行完毕之后且正确执行($?=0), ...
- DVWA靶场练习-Command Injection命令注入
Command Injection 原理 攻击者通过构造恶意参数,破坏命令的语句结构,从而达到执行恶意命令的目的.
- 强烈IDEA这些插件,让你的开发速度飞起来!
大家好,我是大彬~ 俗话说:工欲善其事必先利其器.今天给大家介绍几款我自己经常用的 IDEA 插件,很强大,助力大家开发. 插件安装 以IDEA为例,进入settings->Plugins-&g ...
- Linux下MySQL多实例部署记录
什么是MySQL多实例 简单地说,Mysql多实例就是在一台服务器上同时开启多个不同的服务端口(3306.3307),同时运行多个Mysql服务进程,这些服务进程通过不同的socket监听不同的服务端 ...
- kubernetes中headless类型的service
目录 初识headless类型的service 开始研究headless类型的service headless类型的service之我的理解 初识headless类型的service 第一次使用ran ...
- WPF下获取文件运行路径、运行文件名等
在客户端开发过程中,经常需要获取相对路径的一些资源,而相对路径的就与客户端运行文件的路径息息相关了.在以前的winform开发中,我们可以使用 System.Windows.Forms.Applica ...
- 🏆【JVM技术专区】「编译技术专题」带你彻底认识Java的编译技术
前提概要 Java的class字节码并不是机器语言,要想让机器能够执行,还需要把字节码翻译成机器指令.这个过程是Java虚拟机做的,这个过程也叫编译.是更深层次的编译. 在编译原理中,把源代码翻译成机 ...
- SSH以及ROS远程登录设置保姆级教程
本文用来实现在同一局域网内的两台计算机之间的相互通信,实现一台计算机登录到另一台计算机,本文基于SSH来实现. 1.SSH简介 Secure Shell(SSH)是由 IETF(The Interne ...
- NOIP 模拟 $18\; \rm 老司机的狂欢$
题解 \(by\;zj\varphi\) 一道很有趣的题,我用的动态开点线段树和倍增 首先对于第一问,不难想到要二分,二分时间,因为时间长一定不会比时间短能跑的人多 那么如何 check,先将所有老司 ...