目录
1、命令行参数
1.1、读取参数
1.2、读取脚本名
1.3、测试参数
2、特殊参数变量
2.1、参数统计
2.2、抓取所有的数据
3、移动变量
4、处理选项
4.1、查找选项
4.1.1、处理单个选项
4.1.2、分离参数和选项
4.1.3、处理带值的选项
4.2、使用getopt命令
4.2.1、命令的格式
4.2.2、在脚本中使用getopt
4.3、使用更高级的getopts
5、把选项项标准化
6、获得用户输入
6.1、基本的读取
6.2、超时
6.3、隐藏方式读取
6.4、从文本中读取
完整笔记请前往此处免费获取:https://download.csdn.net/download/qq_55908180/88366003
因为脚本有时要能够与使用者进行交互,shell提供了一些方法可以从用户处获得数据,包含命令行参数(添加在命令后的数据)、命令行选项以及直接从键盘读取输入。
这里只要给出了三种从脚本用户处获取数据的方法:
1、脚本通过位置参数来取回命令行参数并将他们赋值:shift命令,还有三个特殊变量可以用来处理命令行参数
shell会将s#变量设为命令行输入的参数总数。$*变量会将所有参数保存为一个字符串。$@变量将所有变量都保存为单独的词。
2、除了参数外,脚本用户还可以用命令行选项来给脚本传递信息。命令行选项是前面带有单破折线的单个字母。可以给不同的选项赋值,从而改变脚本的行为。
有三种方式来处理命令行选项:1)把它们当作命令行参数一样处理;2)getopt命令;3)getopts命令
3、read命令
使用命令行参数是最基本的向shell脚本传递数据的方法,如:./addem 10 30就是向脚本addem传递了两个命令行参数。
bash shell会把一些称为位置参数的特殊变量分配给输入到命令行中的参数。位置参数变量是标准的数字:$0是程序名,#1是第一个参数,$2是第二个参数,以此类推直到第九个参数。如:
例1:在脚本中使用单个命令行参数
例2:在脚本中使用多个命令行参数的话,则每个参数都必须用空格分开。
例3:也可以在命令行上用文本字符串
注意:如果字符串中包含空格就需要用引号。因为每个参数都是由空格分隔的,所以shell会把空格当成两个值的分隔符!!!!如:
如果脚本需要的命令行参数不止9个,就需要稍微修改一下变量名,即在第9个变量之后,必须要在变量数字周围加上大括号,比如{10}。如:
可以使用$0参数获取shell在命令行启动的脚本。
$0也会带来一些问题,1、如果另一个命令运行shell脚本,命令会和脚本名混在一起,出现在$0的参数里;2、当传给$0变量的实际字符串不仅仅是脚本名,而是完整的脚本路径时,变量$0就会使用整个路径。
basename命令会返回不包含路径的脚本名。如:
也可以用这种方法来编写基于脚本名执行不同功能的脚本。如:
在本例子中,首先利用shell脚本创建了两个不同的文件名:一个通过复制文件创建(addem);另一个是通过链接创建(multem)。
在shell脚本中使用命令行参数时要小心,在使用参数前一定要检查其中是否有数据存在。如:
由于在脚本中使用命令行参数之前应该检查一下命令行参数,但是有的脚本使用了很多命令行参数,检查起来就会比较麻烦。为此,shell提供了一个特殊变量,可以统计一下命令行输入了多少个参数,它就是$#,它含有脚本运行时携带的命令行参数的个数,且可以在脚本的任意地方使用。如:
下面例子是在使用参数前测试参数的数量。如:
这个变量还提供了一个简单的方法来获取命令行中最后一个参数,可以通过${!#}来实现。切记不可以用${$#},要不然会得到意想不到的结果。如:
注意:当命令行上没有任何参数时,$#的值为0,params的值也是0,但是,${!#}变量会返回命令行用到的脚本名。
有时候需要抓取命令行上提供的所有参数,可以不需要先用$#变量判断命令行上有多少参数,$*和$@变量可以用来访问所有的参数。
$*变量会把命令行上提供的所有参数当作一个单词保存,它会把这些参数视作一个整体;
$@变量会把命令行上提供的所有参数当作同一字符串中的多个独立的单词。如:
上面的例子,两个变量产生了同样的输出,下面看看不一样的:
通过for命令遍历这两个特殊的变量时,$*变量会把所有参数当成单个参数,而$@变量会单独处理每个参数。
shift命令能够用来操作命令行参数,该命令会根据他们的相对位置来移动命令行参数。在使用shift命令时,默认它会把每个参数变量向左移动一个位置,即:$3的值移到$2中,$2的值移到$1中,$1的值被删除。如:
这个脚本是通过测试第一个参数值的长度来执行while循环,当第一个参数长度为0时,循环结束。测试完第一个参数后,shift命令会把所有参数的位置移动一个位置。注意:在shift后提供一个参数,就可以一次移动多个位置。
选项是跟在单破折线后面的单个字母,它能改变命令的行为。
表面上看,命令行选项没什么特别的,但是,你也可以像处理命令行参数一样处理命令行选项。
可以利用shift命令来依次处理脚本携带的命令行参数。在提取每个单独的参数时,用case语句来判断某个参数是否为选项。如:
如果在脚本中同时使用选项和参数,可以使用特殊字符双破折线(——)把选项和字符分开。双破折线表明选项列表结束,在双破折线之后,脚本就可以放心把剩下的命令行参数都能做参数来处理了。要检查双破折线,只要在case语句中加一项就可以了。如:
有些选项会带上一个额外的参数值,但命令行选项要求额外的参数时,脚本必须能检测到并正确处理。如:
getopt能够识别命令行参数,因此在脚本中解析它们时会更方便。
命令格式:getopt optstring parameters
optstring是这个过程的关键,它定义了命令行有效的选项字母,还定义了哪些选项字母需要参数值。
首先,在optstring中列出你要在脚本中用到的每个命令行选项字母,然后在每个需要参数值的选项字母后加上一个冒号,getopt命令会基于你定义的optstring解析提供的参数。
这个例子定义了四个有效选项字母:a,b,c,d。冒号(:)被放在字母b后面,因为b选项后面需要一个参数值。
如果指定了一个不在optstring中的选项,默认情况下,getopt会产生一条错误消息,可以在命令后面加上-q选项,可以忽略错误消息。如:
在脚本中可以使用getopt来格式化脚本所携带的任何命令行参数或选项 ,方法是用getopt命令生成的格式化后的版本来替换已有的命令行选项和参数,用set命令能够做到。set命令的选项之一就是双破折线(--),它会把命令行参数替换成set命令的命令行值然后,该方法会把原始脚本的命令行参数传getopt命令,之后再把getopt命令的输出传给set命令,再用getopt格式化后的命令行参数来替换原始的命令行参数。如:set -- $(getopt -q ab:cd "$@")
如:
getopts命令相较于getopt多了一些扩展功能。getopt把命令行上选项和参数处理后只生成一个输出,而getopts的每次调用,只处理命令行上检测到的一个参数,处理完所有参数后,它会退出并返回一个大于0的退出状态码。因此,它非常适合用于解析命令行所有参数的循环中。getopts命令的格式如: getopts optstring variable
optstring值类似于getopt命令中的。有效的字母都会列在optstring中,如果选项字母要求有个参数值,就加一个冒号。要去掉错误消息的话,可以在optstring前加上一个冒号。
getopts命令会用到两个环境变量:如果选项需要跟一个参数值,OPTARG环境变量会保存这个值;OPTIND环境变量保存了参数列表中getopts正在处理的参数位置。如:
除此之外,getopts命令还有几个好用的功能:
- 可以在参数中包含空格
- 把选项字母和参数值放在一起使用,且不加空格
- 该命令还能在命令行上找到所有未定义的选项统一输出成问号
getopts命令知道什么时候停止处理选项,并把参数留给你处理。getopts处理每个选项时,会把OPTIND环境变量值加一,在getopts完成处理时,可以用shift命令和OPTIND值来移动参数。如:
选项 | 描述 |
---|---|
-a | 显示所有对象 |
-c | 生成一个计数 |
-d | 指定一个目录 |
-e | 扩展一个对象 |
-f | 指定读入数据的文件 |
-h | 显示命令的帮助信息 |
-i | 忽略文本大小写 |
-l | 产生输出的长格式版本 |
-n | 使用非交互模式〔批处理) |
-o | 将所有输出重定向到的指定的输出文件 |
-q | 以安静模式运行 |
-r | 递归地处理目录和文件 |
-s | 以安静模式运行 |
-v | 生成详细输出 |
-x | 排除某个对象 |
-y | 对所有问题回答yes |
有时脚本的互动性要求更高,就需要使用read命令,可以从键盘获得输入。
read命令从键盘或另外一个文件描述符中接受输入,在收到输入后,read命令会把数据放进一个变量。如:
read命令包含了 -p 选项,允许用户直接在read命令行指定提示符
read命令会把提示符后输入的所有数据分配给一个变量,除非人为指定多个变量,输入的每个数据值都会分配给变量列表中的下一个变量,如果数量不够,剩下的数据就会全部分配给最后一个变量。
也可以不指定变量,这样的话,read命令会把收到的所有数据都放进特殊环境变量REPLY中。如:
在使用read命令时,脚本有可能会出现一直等待输入的情况,为了避免这种情况,可以使用-t选项指定一个计时器。-t选项指定了read命令等待输入的秒数。当计时器过期后,read命令就会返回一个非零的退出状态码。如:
也可以不对输入过程计时,可以让read命令统计输入的字符数,当输入字符达到预设的个数时,就会自动退出,并把获得的输入赋值给变量。
在这里,-n和1一起,就是告诉read命令在读取一个字符时,就把他赋值给变量。
-s选项可以避免在read命令中输入的数据出现在显示器上。如:
read也可以读取Linux系统上文件里保存的数据,每次调用read它都会从文本中读取一行文本。当文件中没有内容时,read命令会退出并返回非零退出状态码。最常用的方法就是利用cat命令把文件中的数据传给read命令,再把结果通过管道直接传给含有read的whilw命令。如: