一、专题背景

最近使用了个自动化平台(详见自动化运维平台Spug测试)进行每周的变更,效果很不错,平台将大量重复繁琐的操作通过脚本分发方式标准化自动化了,平台核心是下发到各个服务器的shell脚本,感觉有必要对shell脚本做个总结,所以有了写本专题的想法。本专题将结合运维实际介绍shell脚本的各项用法,预计10篇左右,将包括系统巡检、监控、ftp上传下载、数据库查询、日志清理、时钟同步、定时任务等,里面会涉及shell常用语法、注意事项、调试排错等。

二、本文前言

本文是该专题的第五篇。

文章主要介绍如何在脚本执行时传参、如何对传入的参数做基本的处理、如何处理选项、怎样执行用户输出。

三、环境说明

主机名操作系统版本ip备注
shellCentos 7.6.1810172.16.7.100shell测试服务器

四、脚本测试

1.命令行参数

[root@shell param]# more test1.sh #!/bin/bashname=$(basename $0)total=$[ $4 * $5 ]echo 这是第一个参数: $1echo 这是第二个参数: $2echo 这是第三个参数: $3echo 这是第四个参数: $4echo 这是第五个参数: $5echo 脚本名称为 $nameecho $4乘以$5的值为 $total[root@shell param]# ./test1.sh 1 a "b c" 4 5这是第一个参数: 1这是第二个参数: a这是第三个参数: b c这是第四个参数: 4这是第五个参数: 5脚本名称为 test1.sh4乘以5的值为 20

传入的参数可以是数字、字符和字符串

\$0 是脚本名, \$1是第一个参数, \$2 是第二个参数,依次类推,直到第九个参数 $9

2.判断参数个数

[root@shell param]# ./test1.sh ./test1.sh:行4: *  : 语法错误: 期待操作数 (错误符号是 "*  ")这是第一个参数:这是第二个参数:这是第三个参数:这是第四个参数:这是第五个参数:脚本名称为 test1.sh乘以的值为

当脚本执行时未加参数则执行报错,此时需要对脚本进行优化,可以使用特殊变量$#判断传入脚本的参数个数。

[root@shell param]# more test1.sh #!/bin/bashif [ $# -ne 5 ]then    echo 参数个数有误,请重新输入else    name=$(basename $0)    total=$[ $4 * $5 ]    echo 这是第一个参数: $1    echo 这是第二个参数: $2    echo 这是第三个参数: $3    echo 这是第四个参数: $4    echo 这是第五个参数: $5    echo 脚本名称为 $name    echo $4乘以$5的值为 $totalfi[root@shell param]# ./test1.sh 参数个数有误,请重新输入[root@shell param]# ./test1.sh  1 2 3 4参数个数有误,请重新输入[root@shell param]# ./test1.sh  1 2 3 参数个数有误,请重新输入[root@shell param]# ./test1.sh  1 2 3 4 5 6 参数个数有误,请重新输入[root@shell param]# ./test1.sh 1 a "b c" 4 5这是第一个参数: 1这是第二个参数: a这是第三个参数: b c这是第四个参数: 4这是第五个参数: 5脚本名称为 test1.sh4乘以5的值为 20

只有传入的参数个数为5时脚本才能正常运行,避免因为参数个数传入有误造成脚本执行报错。

3.获取所有的参数

[root@shell param]# more test2.sh #!/bin/bashi=1for param in "$*"doecho "参数$i = $param"i=$[ $i + 1 ]donej=1for param in "$@"doecho "参数$j = $param"j=$[ $j + 1 ]done[root@shell param]# ./test2.sh  a b c参数1 = a b c参数1 = a参数2 = b参数3 = c

\$和\$@都可以获取到左右的传入参数,区别是 \$\变量会将所有参数当成单个参数,而 \$@变量会单独处理每个参数。

4.遍历参数

使用shift命令默认情况下它会将每个参数变量向左移动一个位置,可以使用这个方法遍历所有传入的参数。

[root@shell param]# more test3.sh #!/bin/bashi=1while [ -n "$1" ]do  echo "参数$i = $1"  i=$[ $i + 1 ]  shiftdone[root@shell param]# ./test3.sh  a b c参数1 = a参数2 = b参数3 = c

使用while先判断输入的参数1是否存在,如果非空则执行下面的操作:先输出参数$1,然后使用shift将参数\$2移动为新的\$1,如此循环,直至所有参数被遍历。

5.选项处理

[root@shell param]# more test4.sh#!/bin/bashname=$(basename $0)case $1  in'start')        systemctl start docker        ;;'stop')        systemctl stop docker        ;;'restart')        systemctl restart docker        ;;'status')        systemctl status docker        ;;*)            echo "Usage: sh $name {start|stop|restart|status}"        exit 3esac[root@shell param]# ./test4.shUsage: sh test4.sh {start|stop|restart|status}[root@shell param]# ./test4.sh abcUsage: sh test4.sh {start|stop|restart|status}[root@shell param]# ./test4.sh stop[root@shell param]# ./test4.sh start[root@shell param]# ./test4.sh status

case 语句会检查每个参数是不是有效选项。如果是的话,就运行对应 case 语句中的命令。

当参数为start、stop、restart和status时执行对应的命令,若为其它参数则提醒需输入正确命令并退出。

6.用户输入

6.1基本读取

使用read可以从标准输入(键盘)或另一个文件描述符中接受输入,在收到输入后, read 命令会将数据放进一个变量。

[root@shell param]# more test5.sh #!/bin/bashread  -n1 -p  "是否继续 Enter[Y/N]? " optioncase $option inY | y) echoecho "继续执行下一步: Hello World!";;N | n) echoecho "中断执行"exit;;esac[root@shell param]# ./test5.sh 是否继续 Enter[Y/N]? y继续执行下一步: Hello World![root@shell param]# ./test5.sh 是否继续 Enter[Y/N]? N中断执行

-p 选项可以指定提示符“是否继续 Enter[Y/N]?”,-n 选项和值 1 一起使用,告诉 read 命令在接受单个字符后退出。

6.2隐藏读取

[root@shell param]# more test6.sh #!/bin/bashread -t 5 -s -p "Enter your password: " passechoecho "显示输入的密码: $pass "[root@shell param]# ./test6.sh Enter your password: 显示输入的密码: abc123! 

-s 选项可以避免在 read 命令中输入的数据出现在显示器上(实际上,数据会被显示,只是read 命令会将文本颜色设成跟背景色一样)

-t 选项来指定一个计时器,即5秒钟后没输入退出程序。

6.3文件读取

[root@shell param]# more test7.sh #!/bin/bashi=1cat myfile | while read mylinedoecho "第$i行: $myline"i=$[ $i + 1]done[root@shell param]# more myfile abc123!123abc!!123abcabc!123123!abc!abc123[root@shell param]# ./test7.sh 第1行: abc123!第2行: 123abc!第3行: !123abc第4行: abc!123第5行: 123!abc第6行: !abc123

本例使用 read 命令来读取文件数据,对文件使用 cat 命令,将结果通过管道直接传给含有 read 的 while 命令,也可以使用输出重定向方式,参见shell脚本专题(04):循环中的“2.批量新增用户”

五、本文总结

参数传入是脚本执行时的一个重要的方式,可以让脚本的执行更加灵活方便,交互的界面使脚本执行更具可读性。本文介绍了三种交互方式:命令行参数、选项和read方式。掌握了这三种方式会让脚本更优雅功能性更强。

本文所有脚本和安装包文件已上传github:shell-scripts-05

更多请点击:shell专题

©著作权归作者所有:来自51CTO博客作者loong576的原创作品,如需转载,请注明出处,否则将追究法律责任

你的鼓励让我更有动力

赞赏

0人进行了赞赏支持

更多相关文章

  1. flex容器中的四个属性的功能,参数,以及作用
  2. flex容器属性的功能,参数,以及作用
  3. 3.24实例演示flex容器中的四个属性的功能,参数,以及作用
  4. Hystrix 实战经验分享
  5. flex布局:flex容器中的四个属性的功能,参数,以及作用
  6. shell脚本实现mac地址格式转换
  7. 【忆臻解读】Andrej Karpathy提到的神经网络六大坑
  8. 华为防火墙与思科路由器IPsec对接参数
  9. docker 安装脚本

随机推荐

  1. 芋道 Spring Boot Redis 入门(下)
  2. 作为一名JS开发人员,是什么使我夜不能寐[
  3. 芋道 Spring Boot JPA 入门(二)之基于方法
  4. MySQL 8 OCP(1Z0-908)认证考试题库原题(第
  5. 轻轻一扫,立刻扣款,付款码背后的原理你不想
  6. 芋道 Spring Boot JPA 入门(三)之基于注解
  7. 现代生活已经离不开的银行卡支付,背后原理
  8. 链路追踪 SkyWalking 6.x 源码分析 ——
  9. TS与JS中的Getters和Setter究竟有什么用[
  10. 芋道 Spring Boot JdbcTemplate 入门