比赛将近,sh当然也学的差不多了,学到后面,感觉这门语言,,,活该值只能做脚本语言
测试
在程序设计中,有一些东西是不能缺少的:
-
顺序语句
-
判断语句
-
循环语句
-
异常语句 (不是所有语言都有)
顺序语句自不必多说,选择判断语句,在sh中简直是,,,
来看看就知道了.
之前我们曾经提到过查看命令返回值的方式,
查看变量
$? --即可查看命令的返回值
在shellscript中,如果返回值为0即为成功执行,非0值为失败
在shell中实现测试有这样两种方式:
-
使用test命令进行测试
-
使用[ ]运算符进行测试
test命令实际意义不大,不必多说.
使用[ ]来启动一个测试,[ ]的要求就多了,
首先[(空格) 测试内容 (空格)],两侧必须有空格,中间写测试内容
至于,测试的结果,那就需要考虑多种多样的测试符了:
1.文件测试符
文件测试 | 说明 |
---|---|
-b FILE | 当文件存在且是块文件时,返回真,否则为假 |
-c FILE | 当文件存在且是字符设备时,返回真,否则为假 |
-d FILE | 当文件存在且是个目录时,返回真,否则为假 |
-e FILE | 当文件或者目录存在时,返回真,否则为假 |
-f FILE | 当文件存在且为普通文件,返回真,否则为假 |
-x FILE | 当文件存在且为可执行文件时,返回真,否则为假 |
-w FILE | 当文件存在且为可写文件时,返回真,否则为假 |
-r FILE | 当文件存在且为可读文件时,返回真,否则为假 |
-l FILE | 当文件存在且为连接文件时,返回真,否则为假 |
-p FILE | 当文件存在且为管道文件时,返回真,否则为假 |
-s FILE | 当文件存在且大小不为0时,返回真,否则为假 |
-S FILE | 当文件存在且为Socket文件时,返回真,否则为假 |
-g FILE | 当文件存在且设置了SGID时,返回真,否则为假 |
-u FILE | 当文件存在且设置了SUID时,返回真,否则为假 |
-k FILE | 当文件存在且设置了sticky属性时,返回真,否则为假 |
-G FILE | 当文件存在且为有效用户组时,返回真,否则为假 |
-O FILE | 当文件存在且为有效用户组时,返回真,否则为假 |
FILE1 -nt FILE2 | 当文件FILE1比FILE2新时,返回真,否则为假 |
FILE1 -ot FILE2 | 当文件FILE1比FILE2旧时,返回真,否则为假 |
2.字符串测试
字符串测试 | 说明 |
---|---|
-z “string” | 如果string为空,则返回真,否则为假 |
-n “string” | 如果string非空,返回真,否则为假 |
“string1” = “string2” | 如果两个串相等,则返回真,否则为假 |
“string1” != “string2” | 如果两个串不相等,则返回真,否则为假 |
“string1” > “string2” | 字典序,若string1 在string2 前,则为真,否则为假 |
“string1” < “string2” | 字典序,若string1 在string2 后,则为真,否则为假 |
来说说怎么使用吧
cmd=`systemctl status sshd | grep running`
if [ -z "$cmd" ];then -- [ ] 用来启动测试,进行测试时,一定加上引用
echo "srevice GG,restart'
fi
数字测试,可以不加上引号,但是字符串必须加上引号,所以,统一一下,建议加上引号
str1="ABCD"
str2=""
if [ "$str1" = "$str2" ];then
echo "相等"
else
echo "不相等"
fi
同时注意,对于字符串序列的比较,需要对 > 以及 < 进行转义
或者使用 [ [ ] ] 来进行运算
3.整数测试符
测试符 | 说明 |
---|---|
“num1” -eq “num2” | -equal |
“num1” -gt “num2” | -great than |
“num1” -lt “num2” | -less than |
“num1” -ge “num2” | -great equal |
“num1” -le “num2” | -less equal |
“num1” -ne “num2” | -not equal |
用法同上
4.逻辑测试符与逻辑运算符
对,你没有看错,关于逻辑测试的问题,既可以使用逻辑测试符,也可以使用逻辑运算符.
逻辑测试符
测试符 | 说明 |
---|---|
!expression | 取反 |
expression1 -a expression2 | 与运算 |
expression1 -o expression2 | 或运算 |
运算符 | 说明 |
---|---|
! | 取反 |
&& | 与运算 |
|| | 或运算 |
这两个有什么区别呢?
测试符,是对一个式子进行测试,而运算符起码是对两个运算式的运算
[ -e /var/log/1 -a -e /var/log/2 ]
[ -e /var/log/1 ] && [ -e /var/log/2 ]
**测试符就这么多内容,现在说说返回值 : **
sh的返回值是比较恶心的,条件测试的返回值与 echo $? 的结果
$? 是表示上一条命令的结果/返回值 ,说明条件测试的结果,如果为真,则返回值为0.否则为非0
与C-family或者其他语言有很大的不同…
判断
sh中有这几种判断的结构
1. if
2. if-else
3. if-elif-else
4. case语句
可以用if ~ elif ~ else统一介绍这几种语句
if [ test ]; then
command1
elif [ test ]; then
command2
else
command3
fi
注意在sh中if的选择判断语句是不使用括号的..,当然也没有py的游标卡尺那么恶心
下面来看看case语句时怎样使用的 ?
sh中的case与C中的case区别还是很大的:
case VAR in
var1) command1.1 ; command1.2 ;;
var2) command2.1 ; command2.2 ;;
var3) command3.1 ; command3.2 ;;
*) command ;;
esac
使用 ;; case选择的结束
最后,留有 * 表示 其他选项,即 default选项
循环
循环语句也是程序设计语言中所不可缺少的部分
在sh中有下面这几种循环:
**1. for 循环 **
2. while 循环
3. until 循环
4. select 循环
for循环,在很多语言中都提供支持
sh中的for也是多种多样,基本上有以下三种形式:
1.使用列表进行循环
for FRUIT in "apple banana pair peach"
do
echo $FRUIT
done
像这样进行循环即可,但是,列表终归是有限的,
所以有了第二种,动态生成列表的写法(不过必须是有规律的内容)
for i in {1..5} --循环1-5
do
echo $i
done
for i in `seq 1 5` --动态生成列表1-5
do
echo $i
done
for i in `seq 1 2 5` --生成列表{1 3 5}
do
echo $i
done
最后一种,就是C风格的for循环
for ((i=1 ; i<10 ; i++)) --循环打印1-10
do
echo $i
done
sh的脚本编写,经常需要写一些监测系统服务的程序
那么,死循环就显得尤为重要了
for的死循环写法:
for((; 1 :))
do
command
done
2.while循环
其实,客观的讲,while循环应用的场景更多
来看一看语法:
while expression
do
command
done
下面是一个while按行读取文件的程序,可以学习一下
while read LINE
do
echo LINE | awk '{print $1}'
echo LINE | awk '{print $2}'
done < test.txt
那么while的无限循环又该怎么写呢?
while true
do
command
done
while ((1))
do
command
cone
while :
do
command
done
以上三种都属于while的永真循环
最后,还有一种until/select循环,因为应用场景并不是很多
而且可以使用,for,while替代就不说了(懒得不想写)
最后,看看其中的循环控制语句
break continue 与C如出一辙
但是,这两种控制语句,与C中基本用法一致
但是,有一个更人性化的地方
break 1/2/3 ---数字可以指定跳出循环的次数
continue 1/2/3
函数
函数,是一门程序设计语言中不可缺少的特性.
函数的使用,提高了程序的复用性和易用性
来看看sh的函数(中规中矩)
function function_name( )
{
if[ test ];then
command1
command2
fi
while expression
do
command3
command4
done
command x
(return value) --可选项
}
上面便是一个标准的函数模板
emmmmmmmmmmmmmmmmm
感觉,sh函数要谈得没多少….
辣鸡得很
捡些重点的说吧:
1.函数的返回值
sh中的函数返回值,一定会有返回值
如果,显示指定return,则返回return后的值
否则,返回最后一条命令的执行返回值 即为 $?
2. 函数参数
sh的函数之间并不能传递参数
可以调用,命令行参数 $1 $2 $3 $4…
或者,使用set显式指定参数,则将所有参数覆盖
3. 函数库的问题
一般语言,起码会有不少的函数库,
sh也想用吗?
告诉你,没有 , 滚
一般都是自行开发函数库
不过在/etc/init.d/functions中勉强有27个函数
使用 source 命令加载自行开发的函数库
4. 递归
emmm,这个我不想讲,我也讲不清….
sh的学习就这么结束吧
自己的感悟,sh肯定是适合运维的同学去学习,我当时学习sh,一方面是一个比赛需求(TM最后shell命令)
sh的熟练编写需要基于熟练的Linux系统操作,以及Linux常用命令的熟练使用上
最后,是因为我觉得sh 辣鸡,没什么很有意思的特性
草草了之,但是,shellscript中的基本特性说的差不多了
讲个道理,如果不是运维人员,相比与书写shell,看懂shell更为重要
接下来,就该回归主线了,不能浪了
December 10, 2017 11:38 PM