续Shell脚本学习 Day3 脚本开发
开发思路(使用nginx为例)
先思考脚本功能、作用
编写伪代码
定义变量,用于存储变化的值,便于后期维护
安装···
启动···
修改配置文件···
重启文件···
函数使用演示 编写demo1.sh脚本
1 2 3 4 5 6 7 #!/bin/bash print_sth (){ echo "你好呀!" } print_sth
运行演示
1 2 3 [root@localhost ~] [root@localhost ~] 你好呀!
实例一
接收用户输入的数字和符号实现加减乘除运算
编写demo2.sh脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #!/bin/bash print_usage (){ printf "please enter on interger\n" exit 1 } read -p "please input your number:" firstnumif [ -n "`echo $firstnum |sed 's/[0-9]//g' `" ] then print_usage exit 1 fi read -p "Please input your operator:" operatorif [ "${operator} " != "+" ] && [ "${operator} " != "-" ] && [ "${operator} " != "*" ] && [ "${operator} " != "/" ]then echo "只能输入+-*/四个符号" exit 2 fi read -p "please input your number:" secondnumif [ -n "`echo $secondnum |sed 's/[0-9]//g'`" ]then print_usage exit 3 fi echo "${firstnum} ${operator} ${secondnum} " '=' "$((${firstnum}${operator}${secondnum}) )"
运行演示
1 2 3 4 5 6 7 8 9 10 11 [root@localhost ~] please input your number:1 Please input your operator:* please input your number:500 1*500=500 [root@localhost ~] please input your number:1 Please input your operator+ please input your number:2 1+2=3
实例二
更简单的方法
使用参数传递,实现上面的功能
编写demo3.sh
1 2 #!/bin/bash echo $(($1 ))
运行演示
但这个脚本并没有我们demo2.sh的要严谨
实例三
开发检测nginx服务是否运行的脚本
首先引出while循环的使用
1 2 3 while true ;do echo "123456" ;sleep 1;done
执行后用Ctrl+C打断命令
编写demo4.sh脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #!/bin/bash CheckUrl (){ timeout =5 fails=0 success=0 while true do wget --timeout =${timeout} --tries=1 http://lptexas-cub.github.io/ -q -o /dev/null if [ $? -ne 0 ] then let fails=fails+1 else let success+=1 fi if [ ${success} -ge 1 ] then echo "网站运行正常!" exit 0 fi if [ ${fails} -ge 2 ];then echo "网站访问异常!" exit 2 fi done } CheckUrl
http://……./ 处可以使用自己的网站作为测试
let命令运算操作
let命令的执行效果等同于双小括号
但是,双小括号效率更高
let命令实践 1 2 3 4 [root@localhost ~] [root@localhost ~] [root@localhost ~] num+8
可见bash原生命令并不支持运算!
这时我们使用let命令 操作
1 2 3 4 [root@localhost ~] [root@localhost ~] [root@localhost ~] 16
对比一下使用双小括号 操作
1 2 3 4 [root@localhost ~] [root@localhost ~] [root@localhost ~] 16
expr命令基于空格,对于一些运算符需要加 \ 转义后才能使用,如:* 使用expr时需要用 *
expr帮助
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 用法:expr 表达式 或:expr 选项 --help 显示此帮助信息并退出 --version 显示版本信息并退出 将表达式的值列印到标准输出,分隔符下面的空行可提升算式优先级。 可用的表达式有: ARG1 | ARG2 若ARG1 的值不为0 或者为空,则返回ARG1,否则返回ARG2 ARG1 & ARG2 若两边的值都不为0 或为空,则返回ARG1,否则返回 0 ARG1 < ARG2 ARG1 小于ARG2 ARG1 <= ARG2 ARG1 小于或等于ARG2 ARG1 = ARG2 ARG1 等于ARG2 ARG1 != ARG2 ARG1 不等于ARG2 ARG1 >= ARG2 ARG1 大于或等于ARG2 ARG1 > ARG2 ARG1 大于ARG2 ARG1 + ARG2 计算 ARG1 与ARG2 相加之和 ARG1 - ARG2 计算 ARG1 与ARG2 相减之差 ARG1 * ARG2 计算 ARG1 与ARG2 相乘之积 ARG1 / ARG2 计算 ARG1 与ARG2 相除之商 ARG1 % ARG2 计算 ARG1 与ARG2 相除之余数 字符串 : 表达式 定位字符串中匹配表达式的模式 match 字符串 表达式 等于"字符串 :表达式" substr 字符串 偏移量 长度 替换字符串的子串,偏移的数值从 1 起计 index 字符串 字符 在字符串中发现字符的地方建立下标,或者标0 length 字符串 字符串的长度 + TOKEN interpret TOKEN as a string, even if it is a keyword like 'match' or an operator like '/' ( EXPRESSION ) value of EXPRESSION 请注意有许多运算操作符都可能需要由 shell 先实施转义。 如果参与运算的 ARG 自变量都是数字,比较符就会被视作数学符号,否则就是多义的。 模式匹配会返回"\"和" \"之间被匹配的子字符串或空(null);如果未使用"\"和" \", 则会返回匹配字符数量或是 0。 若表达式的值既不是空也不是 0,退出状态值为 0;若表达式的值为空或为 0, 退出状态值为 1。如果表达式的句法无效,则会在出错时返回退出状态值 3。 GNU coreutils online help : <http://www.gnu.org/software/coreutils/> 请向<http://translationproject.org/team/zh_CN.html> 报告expr 的翻译错误 要获取完整文档,请运行:info coreutils 'expr invocation'
我们还可以通过手册对expr命令进行了解
expr命令实践
见Shell脚本学习Day3
expr模式匹配
expr命令支持模式匹配功能(正则表达式)
2个特殊符号
: 计算字符串数量,如abc 3个字符
.* 任意字符串重复0次或者多次
语法
expr <字符串> “:” “.*”
实例
1 2 3 4 [root@localhost ~] 6 [root@localhost ~] 3
bc命令运算操作
bc命令当做计算器来使用,是命令行的计算器
两种形式:交互式与非交互式
支持小数!但除法不支持
bc命令结合管道符
bc案例
计算1~100的总和
数学公式:1+2+3+…+100
法一
使用{1..100}生成1到100的序列,再使用tr将结果中的空格替换为+,最后交给bc命令计算结果
1 echo {1..100}|tr " " "+" |bc
运行演示
1 2 3 4 5 6 [root@localhost ~] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 [root@localhost ~] 1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99+100 [root@localhost ~] 5050
法二
使用seq生成序列
seq的默认分隔符为换行符,可以使用-s参数指定分隔符
运行演示
awk命令支持数值运算操作
语法:
echo “参数1 参数2 … …” |awk ‘{print $1<运算符>$2<运算符>$3… …}’
awk支持小数计算
awk实例
中括号运算操作
语法:
$[表达式]
中括号实例
知识点补充 read命令
shell变量除了直接赋值,或者脚本传递参数,还有就是read命令读取。
read命令是内置命令
1 2 [root@localhost ~] read 是 shell 内嵌
相关参数
-t 等待用户输入的时间,超时命令终止
-p 设置提示信息
1 2 3 4 5 6 7 [root@localhost ~] 请输入:[root@localhost ~] [root@localhost ~] 请输入:123 [root@localhost ~] 123
语法
touch [-acfm][-d<日期时间>][-r<参考文件或目录>] [-t<日期时间>][–help][–version][文件或目录…]
Linux 用户和用户组管理 添加用户
使用useradd命令
语法:
useradd 选项 用户名
参数说明:
选项:
-c comment 指定一段注释性描述。
-d 目录 指定用户主目录,如果此目录不存在,则同时使用-m选项,可以创建主目录。
-g 用户组 指定用户所属的用户组。
-G 用户组,用户组 指定用户所属的附加组。
-s Shell文件 指定用户的登录Shell。
-u 用户号 指定用户的用户号,如果同时有-o选项,则可以重复使用其他用户的标识号。
用户名:
指定新账号的登录名。
实例1 1 useradd –d /home/sam -m sam
此命令创建了一个用户sam,其中-d和-m选项用来为登录名sam产生一个主目录 /home/sam(/home为默认的用户主目录所在的父目录)。
1 su [-fmp] [-c command ] [-s shell] [--help ] [--version] [-] [USER [ARG]]
所谓条件测试,就是得出真假的概念
shell提供条件测试的语法
test命令
中括号
[[ ]] 双中括号
(( )) 双小括号
test条件命令测试
评估一个表达式,结果是真或假
如果结果为真,状态码结果为0;否则,状态码非0
$?取得状态码值
相关参数
-e 判断文件或目录是否存在,存在返回真,否则返回假
语法 1 test 测试参数 测试对象 对结果进行判断执行的逻辑动作
test命令实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [root@localhost ~]# test -e test_file [root@localhost ~]# echo $? 1 ####### [root@localhost ~]# ls anaconda-ks.cfg demo1.sh demo3.sh hello.sh sub_str blog demo2.sh demo4.sh node-v16.16 .0 -linux-x64 [root@localhost ~]# test -e hello.sh [root@localhost ~]# echo $? 0 ### [root@localhost ~]# test -e hello.sh && echo "文件存在!" 文件存在! [root@localhost ~]# echo $? 0
参阅:知无涯学无尽 略有修改
常用 1 2 3 4 5 6 7 8 -e 文件或目录是否存在 -f 文件是否存在 -d 目录是否存在 –r 文件存在并且可读 –w 文件存在并且可写 –x 文件存在并且可执行
判断表达式 1 2 3 4 if test (表达式为真)if test !表达式为假test 表达式1 –a 表达式 2 两个表达式都为真test 表达式1 –o 表达式2 两个表达式有一个为真
判断字符串 1 2 3 4 test –n 字符串 字符串的长度非零,有内容为真test –z 字符串 字符串的长度为零,无内容为真test 字符串1 = 字符串2 字符串相等test 字符串1 != 字符串2 字符串不等
判断整数 1 2 3 4 5 6 test 整数1 –eq 整数2 整数相等(equal)test 整数 1 –ge 整数2 整数1大于等于整数2(greater equal)test 整数1 –gt 整数 2 整数1大于整数2(greater than)test 整数1 –le 整数 2 整数1小于等于整数2(less equal)test 整数1 –lt 整数 2 整数1小于整数2(less than)test 整数1 –ne 整数 2 整数1不等于整数2 (not equal)
判断文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 test File1 –ef File2 两个文件具有同样的设备号和i结点号test File1 –nt File2 文件1比文件2 新test File1 –ot File2 文件1比文件2 旧test –b File 文件存在并且是块设备文件test –c File 文件存在并且是字符设备文件test –d File 文件存在并且是目录test –e File 文件存在test –f File 文件存在并且是正规文件test –g File 文件存在并且是设置了组IDtest –G File 文件存在并且属于有效组IDtest –h File 文件存在并且是一个符号链接(同-L)test –k File 文件存在并且设置了sticky位test –b File 文件存在并且是块设备文件test –L File 文件存在并且是一个符号链接(同-h)test –o File 文件存在并且属于有效用户IDtest –p File 文件存在并且是一个命名管道test –s File 文件存在并且是一个套接字test –t FD 文件描述符是在一个终端打开的test –u File 文件存在并且设置了它的set-user-id位test –r File 文件存在并且可读test –w File 文件存在并且可写test –x File 文件存在并且可执行
test xxx 可以简写成 [ xxx ] 的形式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 注意:在使用"[" 简写test 时,左中括号后面的空格和右括号前面的空格是必需的,如果没有空格,Shell不可能辨别表达式何时开始何时结束. 也就是说 test option file 可以全部改写成: [ option file ] 例如: test –w File 改写成 [ –w File ]
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 if test -n "$1 " then echo "$1 " fi 测试,放到文件当中 if test -n "$1 " then echo "$1 " fi 执行 chmod +x test.sh./test.sh www.linuxpig.com
test命令实践
补充:shell对于真假判断的逻辑,提供&&与运算、||或运算,并且是递进关系
说明
1 2 A 条件 & & B 条件 当A 条件成立,并且执行B 条件A 条件 || B 条件 当A 条件不成立,才会执行B 条件
实例 1 2 3 4 5 6 7 [root@localhost ~] anaconda-ks.cfg demo1.sh demo3.sh hello.sh sub_str blog demo2.sh demo4.sh node-v16.16.0-linux-x64 [root@localhost ~] 文件存在! [root@localhost ~] 文件不存在!!
中括号语法条件测试
脚本中经常进行条件测试,用到最多的,都是中括号[ ]
test和[]的作用相同
注意:[ ] 前后都要加空格!
补充:
在条件测试中使用变量,必须添加双引号!!
实例 1 2 3 4 5 6 7 8 9 10 11 12 [root@localhost ~] [root@localhost ~] [root@localhost ~] 文件存在 [root@localhost ~] rm :是否删除普通空文件 "test" ?y[root@localhost ~] 文件不存在 [root@localhost ~] [root@localhost ~] 文件不存在
双中括号条件测试
与单中括号、test效果相同
特点
:双中括号还支持正则表达式
注意:
和单括号一样需要加括号
双小括号条件测试