Linux指令语法的一般模式
这篇文章主要讲Linux下指令的选项和参数的一般使用模式. 我们先介绍Linux下指令语法的一般模式, 即选项和参数的一般使用模式. 然后讲解如何在程序中添加选项和参数的解析处理功能.
1 Linux指令语法的一般模式
Linux下一条指令的执行往往可以附带有选项和参数. 什么是选项什么是参数呢? 一条指令往往带有非常多的特性, 指令的选项可以用来控制这些特性的使用. 举ls指令为例, 在以下的指令中:
ls -d dir
'-d'就是ls指令的一个选项, 表示只列出目录本身而不是目录下的文件内容. 'dir'则是ls指令的参数, 上面那条ls指令表示列出dir目录. 对于一条指令, 也可以只指定选项或者只指定参数, 又或者两者都不需要, 这要视具体的指令本身和它的使用场景. 如果一条指令既包含选项有包含参数, 那么, 一般都是先输入选项再输入参数.
指令的选项可以按两种情况分类. 一种是按选项的长短分类, 可分为长选项和短选项. 短选项一般形式是一条横杠'-' 后面跟着单个字母, 如'-d'就是一个短选项. 长选项则一般是两条横杠'--'后面跟着一个或者多个单词, 档次往往解释了这个选项的具体作用. 指令的某个选项可能会同时提供短选项和长选项两种形式. 例如grep指令的忽略大小写选项, 它的短选项是'-i', 而长选项则是'--ignore-case'. 短选项可以减少键入的字符, 而长选项则更容易让人明白选项的具体含义. 指令选项的另一种分类则是按选项后面是否有跟参数来划分, 可分为无参选项和带参选项. 上面举的例子中ls'-d'选项和grep的'-i'选项都是无参选项, 我们来看带参选项的一个例子:
jenny@marry:~/src$ grep -n -A 2 'while' opts.sh
6:while getopts "ab:" option
7-do
8- case $option in
这个例子中, 我们利用grep来检索opts.sh文件中包含'while'单词的行, 其中'-A'是一个带参选项, 后面跟着的数字2就是这个选项的参数, 它表示输出匹配行之后额外的两行.
如果不清楚指令的具体用法, 可以通过man指令查看指令的文档说明. 指令的man手册中, 一般会有固定的几张章节, 其中有几个是比较重要的. 首先是DESCRIPTION章节, 这个章节主要介绍这个指令的的功能是什么, 如果不熟悉指令的话, 应该首先阅读这个章节. 另外一个是SYNOPSIS章节, 这个章节主要介绍指令的使用语法的, 举pstree为例, 我们来看看他的SYNOPSIS章节:
PSTREE(1) User Commands PSTREE(2)
NAME
pstree - display a tree of processes
SYNOPSIS
pstree [-a, --arguments] [-c, --compact] [-h, --highlight-all, -Hpid, --highlight-pid pid] [-g] --show-pgids] [-l, --long]
[-n, --numeric-sort] [-N, --ns-sortns [-p, --show-pids] [-s, --show-parents] [-S, --ns-changes] [-u, --uid-changes] [-Z, --security-context]
[-A, --ascii, -G, --vt100, -U, --unicode] [pid, user]
pstree -V, --version
以上pstree指令的SYNOPSIS章节中, pstree主要有两种使用方法. 一种是pstree后面只跟-V或者--version(这也是-V选项的长选项形式)参数, 这将在终端输出pstree的版本信息. 另一种则是pstree后面跟着-V和--version选项以外的选项, 选项之后还需要跟着参数:进程id(pid)或者用户名(user). 选项放在方括号[]中, 如[-a, --arguments]表示这个一个可选选项, 是否要指定这个选项视具体使用情况而言. 如要要了解指令某一选项的具体做用, 可以查看man手册的OPTION章节. 指令包含的选项的具体用法在OPTION这一章节中一般会有详细的介绍.
2 为命令行程序添加选项处理功能
可为为自己编写的命令行程序添加选项处理功能, 这里简要介绍C语言和bash脚本中如何给程序添加选项处理功能.
2.1 为C语言程序添加选项处理功能
Linux上的glibc提供了getopt函数, 该函数可用来处理指令的输入选项.
通过:
man 3 getopt
可以查看getopt函数使用手册. getopt的手册里除了介绍它的使用方法外, 还有具体的使用样例, 对于理解它的使用很有帮助.
getopt的函数原型:
int getopt(int argc, char * const argv[], const char *optstring);
其中, optstring参数是一个定义了选项的字符串, 比如
char *optstring = "ab";
表示有可接收两个无参选项'-a'和'-b'. 如果要指定带参选项, 则可以使用:
char *optstring = "ab:";
以上optstring表示接收一个无参选项'-b'和一个带参选项'-b'. 当getopt解析到一个带参选项时, 它会尝试提取选项的参数. 这时, 可以利用optarg(char *类型)来访问该选项的参数. optarg是glibc库中定义好的, 可以直接使用.
处理完指令的选项, 如何获得选项后面的指令参数呢? 这时可以利用optind变量. optind是一个整形变量, 和optarg变量类似, optind变量也是预先定义好可以直接使用的.getopt函数执行前, optind的值为0. 后续getopt函数每处理完一个选项, optind便会先前移动相应步长. 最终, optind总是指向下一个待处理的输入选项或者参数.所以, 在处理完所有的指令选项之后, argv[optind]...argv[argc-1]便是指令的输入参数了.
getopt只能用来处理短选项, 如果要处理长选项的话, 可以使用geopt_long或者get_opt_long_only函数. 同getopt一样, 这两个函数也有相应的man手册和参考样例.
2.2 为bash脚本添加选项处理功能
类似与C中的getopt函数, bash中内置了可以用来处理getopts命令解析指令选项. getopts指令的optstring的格式和C中getopt函数类似. 同时, getopts命令也有OPTARG变量指向带参选项的参数和OPTIND变量指向下一个待解析的选项或参数. 来看一个使用bash的getopts内置指令解析命令行选项的例子:
#!/bin/sh
while getopts "ab:" option
do
case $option in
a) echo this is a option;;
b) echo this is b option, and the argument is $OPTARG;;
\?) echo unknown opton: $option;;
esac
done
以上例子中, 利用getopts内置指令解析了无参选项'-a', 和带参选项'-b'. 选项后面若是还有参数待处理要怎么办了? 这时候可以利用bash中的参数移位指令shift, 来看看具体如何操作:
#!/bin/sh
while getopts "ab:" option
do
case $option in
a) echo this is a option; shift 1;;
b) echo this is b option, and the argument is $OPTARG; shift 2;;
\?) echo unknown opton: $option;;
esac
done
echo arguments: $@
我们看到, 每处理完一个选项就执行一次shift让参数往前移动一位或者两位. 这样到最后, 处理所有选项后$@便包含剩下的参数. 来看看执行效果:
jenny@marry:~/src$ sh opts.sh -a -b hello arg1 arg2
this is a option
this is b option, and the argument is hello
arguments: arg1 arg2
jenny@marry:~/src$
我们可以看到, 通过执行shift指令, 解析网指令选项后$@的值为"arg1 arg2", 而这便是我们需要的跟在指令选项后的指令参数.
最后更新:2017-07-16 21:32:29