• Home
  • About
    • Road to Coding photo

      Road to Coding

      只要那一抹笑容尚存, 我便心无旁骛

    • Learn More
    • Email
    • Github
  • Posts
    • All Posts
    • All Tags

ShellScript(三)

10 Dec 2017

比赛将近,sh当然也学的差不多了,学到后面,感觉这门语言,,,活该值只能做脚本语言

测试

在程序设计中,有一些东西是不能缺少的:

  1. 顺序语句

  2. 判断语句

  3. 循环语句

  4. 异常语句 (不是所有语言都有)

顺序语句自不必多说,选择判断语句,在sh中简直是,,,

来看看就知道了.

之前我们曾经提到过查看命令返回值的方式,

查看变量

$?                     --即可查看命令的返回值

在shellscript中,如果返回值为0即为成功执行,非0值为失败

在shell中实现测试有这样两种方式:

  1. 使用test命令进行测试

  2. 使用[ ]运算符进行测试

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



ShellScript Share Tweet +1