Linux之shell编程

一、Bash变量

1) Bash变量与变量分类

1、 定义:变量是计算机内存的单元,其中存放的值可以改变

2、 变量命令规则

#变量名必须以字母或下划线开头,名字中间只能由字母、数字和下划线组成

#变量名的长度不得超过255个字符

#变量名在有效的范围内必须是唯一的

#在Bash中,变量的默认类型都是字符串类型(这点尤其要注意)

3、 变量按照存储数据分类

字符串型

整形

浮点型

日期型

4、 变量的分类

a、用户自定义变量

变量自定义的

b、环境变量

这种变量中主要保存的是和系统操作环境相关的数据。变量可以自定义,

但是对系统生效的环境变量名和变量作用是固定的

c、位置参数变量

就是预定义变量的一种。这种变量主要是用来向脚本当中传递参数或数据

的,变量名不能自定义,变量作用是固定的

d、预定义变量

是Bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的。

2) 用户自定义变量

1、 定义变量:变量名=变量值(或者:变量名=“字符串”)

注意:等号左右不能有空格

2、 最简单的变量调用:echo $变量名   例如:echo $x;echo $name

3、 set -u 命令:正常情况下,比如输入echo $a ,但是并没有定义变量a ,就会输出空,这个时候就不清楚是变量值为空还是没有这个变量。执行set -u 命令后系统会明确提示没有变量。

4、 删除变量:unset 变量名

5、 变量叠加: 例子:x=123  x="$x"456  则x变成123456

x=${x}789,则x变成123789

6、 set 查看已有变量

3) 环境变量

1、 环境变量与自定义变量的区别

环境变量是全局变量,用户自定义变量是局部变量。用户自定义变量只在当前shell中生效,环境变量在当前shell和这个shell的所有子shell中生效。

2、 环境变量

对系统生效的环境变量名和变量作用是固定的。环境变量建议大写

3、 设置环境变量

export变量名=值(或者先定义变量,再 export 变量名)

变量名=变量值

export 变量名

4、 查看环境变量

set #查看所有变量

env #只查看环境变量

5、 删除环境变量

unset 变量名

6、 常用环境变量

HOSTNAME:主机名

SHELL:当前shell

TERM:终端环境

HISTSIZE:历史命令条数

SSH_CLIENT:当前操作环境是用ssh连接的,这里记录客户端ip

SSH_TTY:ssh连接的终端时pts/1

USER:当前登录的用户

PATH:系统搜索命令的路径

echo $PATH(查看PATH环境变量)

自定义的脚本可以通过变量叠加到PATH中,直接输入脚本名即可执行

PATH="$PATH":脚本所在目录,例如:PATH=“$PATH”:/root/sh

(重启会失效,永久生效需要写入文件中)

#增加PATH变量的值

7、 PS1环境变量

\d:显示日期。格式为“星期 月 日”

\H:显示完整的主机名。如默认主机名“localhost.localdomain”

\t:显示24小时制时间,格式为“HH:MM:SS”

\A:显示24小时制时间,格式为“HH:MM”

\u:显示当前用户名

\w:显示当前所在目录的完整名称

\W:显示当前所在目录的最后一个目录

\$:提示符。root用户会显示"#",普通用户会显示"$"

4) 语系变量

1、 当前语系查询

locale  #查询系统语系

LANG=zh_CN.UTF-8代表中文语系

LC_ALL:定义整体语系的变量

echo $LANG  #查看系统当前语系

locale -a | more  #查看Linux支持的所有语系

2、 查询系统默认语系

在/etc/sysconfig/i18n中,是永久生效的,下次开机后的语系

3、 Linux中文支持

前提条件,正确安装的中文字体和中文语系

#如要有图形界面,可以正确支持中文显示

#如果使用第三方远程工具,只要正确设置语系,就能显示中文

#如果使用纯字符洁面,必须使用第三方插件(如zhcon等)

5) 位置参数变量

1、 位置参数变量

位置参数变量

作用

$n

n为数字,$0代表命令本身,$1-$9是传入的第一到第九个参数,十以上用大括号包含,如${10}

$*

这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体,(循环一次)

$@

这个变量也代表命令行中所有的参数,不过$@把每个参数区别对待(输入几个参数循环几次)

$#

这个变量代表命令行中所有参数的个数(输入几个参数 输出统计)

例子:

vi test.sh

#!/bin/bash

num1=$1  #取位置变量为1的数

num2=$2  #取位置变量为2的数

sum=$(($num1+$num2))  #Linux中要进行运算要有$(())

echo $sum

 

chmod 711 ./test.sh

./test.sh 10 11 #其中./test.sh是位置变量为$0的变量,10是位置变量为$1的变量,11是位置变量为$2的变量,传递到脚本文件中进行计算

 

注意:for循环中,要用"$*"和"$@",要用双引号

6) 预定义变量

1、 作用

预定义变量

作用

$?

最后一次执行的命令的返回状态。如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。

$$

当前进程的进程号(PID)

$!

后台运行的最后一个进程的进程号(PID)

 

2、 接收键盘输入

read [选项] [变量名]

选项:

         -p“提示信息”:在等待read输入时,输出提示信息

         -t秒数:read命令会一直等待用户输入,使用此选项可以指定等待时间

         -n字符数:read命令只接受指定的字符数,就会执行

         -s:隐藏输入的数据,适用于机密信息的输入

注意:

a、 位置参数变量由于没有提示,因此只适用于脚本的作者使用。我们更加常用的是read 命令。

b、 换行: echo -e "\n"。

         要有参数-e ,echo 才会识别转义符

二、Shell运算符

1) declare命令

1、 declare声明变量类型

[root@localhost ~]# declare [+/-] [选项] 变量名

选项:

-:给变量设定类型属性

+:取消变量的类型属性

-a:将变量声明为数组型

-i:将变量声明为整数型(integer)

-x:将变量声明为环境变量

-r:将变量声明为只读变量

-p:显示指定变量的被声明的类型

2、 把变量声明为数值型

[root@localhost ~]# aa=11

[root@localhost ~]# bb=22

#给变量aa和bb赋值

[root@localhost ~]# declare -i cc=$aa+$bb

#声明变量cc的类型是整数型,它的值是aa和bb的和

3、 声明数组变量

定义数组

movie[0]=zp

movie[1]=tp

declare -a movie[2]=live

查看数组

echo ${movie} #默认调用下标为0的值

echo ${movie[2]}

echo ${movie[*]} #遍历数组所有值

4、 声明环境变量

declare -x 与export相似,export实质上就是declare -x

5、 声明变量只读属性

declare -r test

#给test赋予只读属性,但是请注意只读属性会让变量不能修改不能删除,甚至不能取消只读属性

6、 查询变量的属性

declare -p          #查询所有变量的属性

declare -p 变量名   #查询指定变量的属性

2) 数值运算方法

方法1:在要进行数值运算的变量前加上declare改变变量类型

方法2:expr或let数值运算工具

[root@localhost ~]# aa=11

[root@localhost ~]# bb=22

#给变量aa和变量bb赋值

[root@localhost ~]# dd=$(expr $aa + $bb)

#dd的值是aa和bb的和。注意“+”号两侧必须有空格

方法3:$((运算式))或$[运算式]

[root@localhost ~]# aa=11

[root@localhost ~]# bb=22

[root@localhost ~]# ff=$(( $aa+$bb ))

[root@localhost ~]# gg=$[ $aa+$bb ]       

 

运算符

优先级

运算符

           说明

13

-、+

单目负、单目正

12

!、~

逻辑非、按位取反或补码

11

*、/、%

乘、除、取模

10

+、-

加、减

9

<<、>>

按位左移、按位右移

8

<=、>=、<、>

小于或等于、大于或等于、小于、大于

7

==、!=

等于、不等于

6

&

按位与

5

^

按位异或

4

|

按位或

3

&&

逻辑与

2

||

逻辑或

1

=、+=、-=、*=、/=、%=、&=、^=、|=、<<=、>>=

赋值、运算且赋值

 

3) 变量测试

变量置换方式

变量y没有设置

变量y为空值

变量y设置值

X=${y-新值}

X=新值

X为空

X=$y

X=${y:-新值}

X=新值

X=新值

X=$y

X=${y+新值}

X为空

X=新值

X=新值

X=${y:+新值}

X为空

X为空

X=新值

X=${y=新值}

X=新值

y=新值

X为空
y值不变

X=$y

y值不变

X=${y:=新值}

X=新值

y=新值

X=新值

y=新值

X=$y

y值不变

X=${y?新值}

新值输出到标准错误输出(就是屏幕)

 

X为空

 

X=$y

X=${y:?新值}

新值输出到标准错误输出

新值输出到标准错误输出

 

X=$y

1、 变量测试在脚本优化时使用

2、 例子:测试x=${y-新值}

[root@localhost ~]# unset y

[root@localhost ~]# x=${y-2}

[root@localhost ~]# echo $x --> x=2

[root@localhost ~]# y="" --> 将y的值设为空值

[root@localhost ~]# x=${y-2}

[root@localhost ~]# echo $x --> x= 空

[root@localhost ~]# y=1

[root@localhost ~]# x=${y-2}

[root@localhost ~]# echo $x --> x=1

4) 缺点

shell变量的缺点,是个弱类型,默认是字符串类型的,不能进行数学运算。

三、环境变量配置文件

1) 简介

1、 作用:定义每个用户的操作环境。

2、 source命令

[root@localhost ~]# source 配置文件  或  [root@localhost ~]# . 配置文件

注:修改配置文件后,必须注销重新登录才能生效,source命令可以不用。

3、 放在etc目录下对所有用户生效,放在家目录下只对当前用户登录起作用

2) 功能

1、 配置文件生效顺序

环境变量加载过程分为两条线路。如果不输入用户名密码的登陆方式,例如用root切换用户,这时走的如图这条线路;如果输入用户名密码完整登陆方式从左到右的两条线路。

 

a、 正常启动顺序

 

 

b、 非正常启动

 

 

2、 /etc/profile的作用:

USER变量

LOGNAME变量

MAIL变量

PATH变量

HOSTNAME变量

HISTSIZE变量

umask

调用/etc/profile.d/*.sh文件

3、 ~/.bash_profile的作用

调用了~/.bashrc文件

在PATH变量后面加入了“:$HOME/bin”这个目录

4、 ~/.bashrc的作用

定义默认别名

调用/etc/bashrc

5、 /etc/bashrc的作用

PS1变量

umask

PATH变量

调用/etc/profile.d/*.sh文件

3) 其它配置文件

1、 注销时生效的环境变量配置文件

~/.bash_logout

#一般是空的,可以在里面添加命令,比如注销时清空历史命令

2、 其它配置文件

~/.bash_history

#存储历史命令文件,是存在硬盘的

#退出登录后,新执行的命令才会写入~/.bash_history中

3、 Shell登录信息

a、 本地终端欢迎信息:/etc/issue

转义符

作用

\d

显示当前系统日期

\s

显示操作系统名称

\l

显示登录的终端号,这个比较常用

\m

显示硬件体系结构,如i386、i686等

\n

显示主机名

\o

显示域名

\r

显示内核版本

\t

显示当前系统时间

\u

显示当前登录用户的序列号

b、 远程终端欢迎信息:/etc/issue.net

#转义符在/etc/issue.net文件中不能使用

#是否显示此欢迎信息,由ssh的配置文件/etc/ssh/sshd_config决定,加入“Banner /etc/issue.net”行才能显示(记得重启SSH服务)

c、  登录后欢迎信息:/etc/motd

#不管是本地登录,还是远程登录,都可以显示此欢迎信息

四、正则表达式

1) 正则表达式

1、 定义:正则表达式是用于描述字符排列和匹配模式的一种语法规则。它主要用于字符串的模式分割、匹配、查找及替换操作。主要用于模糊匹配。

2、 正则表达式与通配符

不同点:

a、正则表达式是用来在文件中匹配字符串的,而通配符是用来匹配文件名;

b、正则表达式是包含匹配的,通配符是完全匹配的;

c、搜索字符串的命令(grep、awk、sed等)支持正则表达式,而ls、find、cp是用来查看文件名的,不支持正则表达式。

①通配符

* :匹配任意内容

? :匹配任意一个内容

[]:匹配中括号中的一个字符

②基础正则表达式

元字符

作用

*

前一字符匹配0次或任意多次

.

匹配除了换行符外任意一个字符

^

匹配行首。例如:^hello会匹配以hello开头的行

$

匹配行尾。例如:hello&会匹配以hello结尾的行

[]

匹配中括号中指定的任意一个字符,只匹配一个字符。

例如:[aoeiu]匹配任意一个元音字母,[0-9]匹配任意一位数字,[a-z][0-9]匹配小写字和一位数字构成的两位字符。

[^]

匹配除中括号的字符以外的任意一个字符。例如:[^0-9]匹配任意一位非数字字符,[^a-z]表示任意一位非小写字母

\

转义符。用于取消讲特殊符号的含义取消

\{n\}

表示其前面的字符恰好出现n次。例如:[0-9]\{4\}匹配4位数字,[1][3-8][0-9]\{9\}匹配手机号码

\{n,\}

表示其前面的字符出现不小于n次。例如:[0-9]\{2,\}表示两位及以上的数字。

\{n,m\}

表示其前面的字符至少出现n次,最多出现m次。例如:[a-z]\{6,8\}匹配6到8位的小写字母

注:?和()是扩展正则;

"*"前一个字符匹配0次,或任意多次

"a*"

#匹配所有内容,包括空白行,a可以是0个,也可以是任意多个

"aa*"

#匹配至少包含一个a的行

"aaa*"

#匹配至少包含两个连续a的字符串

 

"."匹配除了换行符外任意一个字符

"s..d"

#匹配在s和d这两个字母之间一定有两个字符的单词

"s.*d"

#匹配在s和d字母之间有任意字符

".*"

#匹配所有内容

 

"^"匹配行首(后面的字符为行首),"$"匹配行尾(前面的字符为行尾)

"^M"

#匹配以大写"M"开头的行

"n$"

#匹配以小写"n"结尾的行

"^$"

#匹配空白行

 

"[]"匹配括号中指定的任意一个字符,只匹配一个字符

(与通配符中的[]相同)

"s[ao]id"

#匹配s和i字母中,要么是a、要么是o

"[0-9]"

#匹配任意一个数字

"^[a-z]"

#匹配以小写字母开头的行

 

"[^]"匹配除中括号的字符以外的任意一个字符

"^[^a-z]"

#匹配不以小写字母开头的行

"^[^a-zA-Z]"

#匹配不用字母开头的行

 

"\"转义符(取消特殊符号的功能)

"\.$"

#匹配使用"."结尾的行

 

"\{n\}"表示其前面的字符恰好出现n次("\"是让{}丧失作用)

"a\{3\}"

#匹配a字母连续出现3次的字符串

"[0-9]\{3\}"

#匹配包含连续的三个数字的字符串(三个数字可不相同)

 

"\{n,\}"表示其前面的字符出现不小于n次

"^[0-9]\{3,\}[a-z]"

#匹配最少用连续三个数字加上一个字母开头的行。

 

注意:正则表达式是包含匹配,如果没有定界符(用其他字母将其分开),

其实"\{n\}"与"\{n,\}"相同。

 

"\{n,m\}"匹配其前面的字符至少出现n次,最多出现m次。(有等于)

"sa\{1,3\}i"

#匹配在字母s和字母i之间有至少一个a,最多三个a

3、 例子

匹配日期格式YYYY-MM-DD(通过-作为定界符)

"[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}"

匹配IP地址(匹配在文件中提取出来的IP地址)

"[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"

2) 字符截取命令

1、 cut字段提取命令

a、grep是行提取命令

b、cut是列提取命令

[root@localhost ~]# cut [选项] 文件名

-f 列号:提取第几列,提取多个列时,之间用“,”隔开

-d 分隔符:按照指定分隔符分割整个列,默认使用制表符tab。

当列之间有较为明确的分隔符可以使用时,可以使用cut,但是使用像空格这类的分隔符时,cut就无法使用了。

2、 printf命令

a、 print ‘输出类型输出格式’ 输出内容

b、 输出类型

%ns:输出字符串。n是数字指代输出几个字符

%ni:输出整数。n是数字指代输出几个数字

%m.nf:输出浮点数。m和n是数字,指代输出的整数位数和小数位数

           如%8.2f代表共输出8位数,其中2位是小数,6位是整数。

c、  输出格式

\a:输出警告声音

\b:输出退格键,也就是Backspace键

\f:清除屏幕

\n:换行

\r:回车,也就是Enter键

\t:水平输出退格键,也就是Tab键

\v:垂直输出退格键,也就是Tab键

c、  例子

printf不支持数据流操作,不能用管道符。

printf '%s\t%s\t%s\n' 1 2 3 4 5 6 --> 此时才会正确输出:

1       2     3

4       5     6

使用printf输出命令,必须明确指出所有的格式

如果想要使用printf读取文件中的内容就需要:

printf '%s' $(cat student.txt)  不调整输出格式

printf '%s\t%s\t%s\t%s\n' $(cat student.txt) 调整输出格式

注:

awk命令的输出中支持print和printf命令;

print在每个输出之后会在自动加入换行符,但Linux系统中默认没有print

命令;

printf是标准格式输出命令,并不会自动加入换行符,如需换行,需要手动

加入换行符。

3、 awk命令

a、 awk  '条件1{动作1} 条件2{动作2} 条件3{动作3}…' 文件名

#条件(Pattern)

一般使用关系表达式作为条件

x > 10判断变量x是否大于10

x>=10大于等于

x<=10小于等于

#动作(Action)

格式化输出

流程控制语句

注:一个条件满足,就执行条件后面{}内的动作。没有条件就无条件执行{}

内的动作,如果有条件,就只有满足条件才能执行{}内的动作。printf

中的转移符号都要用""括起来。

 

awk的流程:依次读取每一行数据,读取完一行数据后,进行条件判

断,如果满足条件,就执行该条件对应的动作,其中将$0赋予为文件

名,剩下的每一列依次为$1\$2...,判断完一行后,继续判断下一行,

直到文件全部判断完。

b、 举例

#awk '{print $2 "\t" $4}' 文件名

#df -h | grep “/dev/vda1”| awk ‘{print $1 “\t”$5}’

c、  BEGIN和END命令

awk 'BEGIN{print "test"}{print $2 "\t" $4}END{print "test"}' student.txt

BEGIN:在读取数据,放入指定变量之前,就先执行BEGIN后面{}里的内容。

END:所有动作执行完后,只要到了结尾,就执行END后面{}里的内容。

d、 FS内置变量

定义awk的分隔符,awk默认的分隔符既可以是空格,也可以是tab。

awk 'BEGIN{FS=":"}'

#将awk的分隔符定义为“:”

e、 关系运算符

都是利用位置参数变量来传递值的。

4、 sed命令

a、 作用

sed主要是用来将数据进行选取、替换、删除、新增的命令。

sed [选项] ‘[动作]’ 文件名

选项:

          -n:一般sed命令会把所有数据都输出到屏幕,如果加入此选择则

                 只会把经过sed命令处理的行输出到屏幕。

          -e:允许对输入数据应用多条sed命令编辑

          -i:用sed的修改结果直接修改读取数据的文件,而不是由屏幕输出

动作:

-a:追加,在当前行后添加一行或多行

  -c:行替换,用c后面的字符串替换原数据行

  -i:插入,在当期行前插入一行或多行

  -d:删除,删除指定的行

  -p:打印,输出指定的行

  -s:字串替换,用一个字符串替换另外一个字符串

     格式“行范围s/旧字串/新字串/g”(和vim中的替换格式类似)

b、 举例

#sed –n ‘2p’文件名(查看文件的第二行)

3) 字符处理命令

1、 sort命令

a、 排序命令sort

sort [选项] 文件名

选项:

-f:忽略大小写

  -n:以数值型进行排序,默认使用字符串型排序

  -r:反向排序

  -t:指定分隔符,默认是分隔符(即制表符)

        -k n[,m]:按指定字段范围排序。从第n字段开始,m字段结束

b、 举例

sort /etc/passwd(排序用户信息文件)

sort -r /etc/passwd(反向排序)

2、 wc命令

wc [选项] 文件名

选项:

-l:只统计行数

-w:只统计单词数

-m:只统计字符数

五、条件判断与流程控制

1) 条件判断式语句

1、 按照文件类型进行判断

测试选项

作用

-b文件

判断该文件是否存在,并且是否为块设备文件(是块设备文件为真)

-c文件

判断该文件是否存在,并且是否为字符设备文件(是字符设备文件为真)

-d文件

判断该文件是否存在,并且是否为目录文件(是目录文件为真)

-e文件

判断该文件是否存在(存在为真)

-f文件

判断该文件是否存在,并且是否为普通文件(是普通文件为真)

-L文件

判断该文件是否存在,并且是否为符号链接文件(是符号链接文件为真)

-p文件

判断该文件是否存在,并且是否为管道文件(是管道文件为真)

-s文件

判断该文件是否存在,并且是否为非空(非空为真)

-S文件

判断该文件是否存在,并且是否为套接字文件(是套接字文件为真)

注:标红的为常用命令;块设备文件和字符设备文件是系统中的特殊文件。

2、 两种文件判断格式

a、 test [选项] [文件名]

b、 [ [选项] [文件名] ]

#建议用b方法,最外中括号是要用空格的

3、 按照文件权限进行判断

测试选项

作用

-r文件

判断该文件是否存在,并且是否该文件拥有读权限(有读权限为真)

-w文件

判断该文件是否存在,并且是否该文件拥有写权限(有写权限为真)

-x文件

判断该文件是否存在,并且是否该文件拥有执行权限(有执行权限为真)

-u文件

判断该文件是否存在,并且是否该文件拥有SUID权限(有SUID权限为真)

-g文件

判断该文件是否存在,并且是否该文件拥有SGID权限(有SGID权限为真)

-k文件

判断该文件是否存在,并且是否该文件拥有SBit权限(有SBit权限为真)

注:不区分用户组还是用户,有该权限就会显示

4、 两个文件之间进行比较

测试选项

作用

文件1 -nt 文件2

判断文件1的修改时间是否比文件2的新(如果新则为真)

文件1 -ot 文件2

判断文件1的修改时间是否比文件2的旧(如果旧则为真)

文件1 -ef文件2

判断文件1是否和文件2的Inode号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法。

 

5、 两个整数之间比较

测试选项

作用

整数1 -eq 整数2

判断整数1是否和整数2相等(相等为真)

整数1 -ne 整数2

判断整数1是否和整数2不相等(不相等为真)

整数1 -gt 整数2

判断整数1是否大于整数2(大于为真)

整数1 -lt 整数2

判断整数1是否小于整数2(小于为真)

整数1 -ge 整数2

判断整数1是否大于等于整数2(大于等于为真)

整数1 -le 整数2

判断整数1是否小于等于整数2(小于等于为真)

 

6、 字符串的判断

测试选项

作用

-z 字符串

判断字符串是否为空(为空返回真)

-n 字符串

判断字符串是否为非空(非空返回真)

字符串1==字符串2

判断字符串1是否和字符串2相等(相等返回真)

字符串1!=字符串2

判断字符串1是否和字符串2不相等(不相等返回真)

 

7、 多重条件判断

测试选项

作用

判断1 –a 判断2

逻辑与,判断1和判断2都成立,最终的结果才为真

判断1 –o 判断2

逻辑或,判断1和判断2有一个成立,最终的结果就为真

!判断

逻辑非,使原始的判断式取反

 

2) 单分支if语句

1、 格式

if [条件判断式];then

程序

fi

 

或者

 

if[条件判断式]

    then

程序

                 fi

                 注:a、if语句使用fi结尾,和一般语言使用大括号结尾不同;

b、[ 条件判断式 ]就是使用test命令判断,所以中括号和条件判断式之间

必须有空格。

c、then后面跟符合条件之后执行的程序,可以放在[]之后,用分号“;”

分割。也可以换行写入,就不需要“;”了。

2、 举例

a、 判断登陆的用户是否为root

 

#!/bin/bash

test=$(env | grep “USER”| cut –d “=”-f 2)

if[“$test”==root]

     then

     echo“Current user is root”

fi

b、 判断分区使用率

#统计根分区使用率

#!/bin/bash

test=$(df -h | grep sda1 | awk '{print $5}' | cut -d "%" -f 1)

#把根分区使用率作为变量值赋予变量rate

 

if [ "$test" -ge "90" ]

then

echo "fen qu shi yong is full"

fi

3) 双分支if语句

1、 格式

if [ 条件判断式 ]

then

条件成立时程序,执行的

else

 条件不成立,执行的另一个程序

fi

2、 举例

a、 判断apache是否启动

#!/bin/bash

 

test=$(ps aux | grep httpd | grep –v grep)

#截取httpd进程,并把结果赋予变量test

if [ -n "$test" ]

#判断test是否为空

then

#如果不为空则执行这段程序 把结果写入/tmp/autostart-acc.log 中

echo " $(date) httpd is ok " >> /tmp/autostart-acc.log

else

#如果为空这执行这段程序

#首先启动httpd服务

/etc/rc.d/init.d/httpd start &>/dev/null

#然后把事件记录在错误日志中

echo " $(date) httpd is no \n httpd is autostart now" >> /tmp/autostart-err.log

fi

注:脚本名不能包含文件名,否则命令执行ps进程搜索会搜索到自身,从而导致脚本失效。

4) 多分支if语句

1、 格式

if [ 条件判断式1 ]

then

        当条件判断式1成立时,执行程序1

elif [ 条件判断式2 ]

then

        当条件判断式2成立时,执行程序2

…省略更多条件…

else

        当所有条件都不成立时,最后执行此程序

fi

2、 举例

#!/bin/bash

read -t 30 -p "Please input num1:" num1

read -t 30 -p "Please input num2:" num2

read -t 30 -p "Please input operator:" ope

if [ -n "$num1" -a -n "$num2" -a -n "$ope" ]

then

test1=$(echo $num1 | sed 's/[0-9]//g')

test2=$(echo $num2 | sed 's/[0-9]//g')

if [ -z "$test1" -a -z "$test2" ]

then

         if [ "$ope" == '+' ]

         then

                result=$(($num1+$num2))

 

         elif [ "$ope" == '-' ]

         then

                result=$(($num1-$num2))

 

         elif [ "$ope" == '/' ]

         then

                result=$(($num1 / $num2))

 

         elif [ "$ope" == '*' ]

         then

                result=$(($num1*num2))

 

         else

         echo "Error: the input operator is worng, please input +-*/"

                exit 111

         fi

  else

         echo "Error: Please input numbers!"

         exit 222

  fi

  echo "$num1 $ope $num2 is $result"

else

  echo "Error: You input null value!"

  exit 333

fi

错误小结:test1=$(echo $num1 | sed 's/[0-9]//g')  sed后有空格

  if [ -z "$test1" -a -z "$test2" ]  if后有空格[]内前后有空格

 if [ "$ope" == '+' ]   ==左右有空格

 echo "Error: Please input numbers![0-9]"

     exit 20 后面数字太大的话用,echo $?将不会正确显示数字。

3、 判断用户输入的是什么文件

#!/bin/bash

#判断用户输入的是什么文件

read -t 30 -p "Please input a file name:" file

#接收键盘的输入,并赋予变量file

if [ -z "$file" ]

#判断file变量是否为空

then

echo "Error, please input a file name!"

exit 11

elif [ ! -e "$file" ]

#判断file的值是否存在

then

echo "Your input is not a file name!"

exit 22

elif [ -f "$file" ]

#判断file的值是否为普通文件

then

echo "$file is a regular file!"

elif [ -d "$file" ]

#判断file的值是否为目录文件

then

echo "$file is a directory !"

else

echo "$file is another file!"

fi

5) 多分支case语句

1、 格式

case $变量名 in

  "值1")

       如果变量值等于值1,执行程序1

       ;;

  "值2")

       如果变量值等于值2,执行程序2

       ;;

  ……

  ……

   *)

      如果变量值都不是以上值,则执行此程序

      ;;

esac

 

#与if多分支最大区别是,case语句只能判断一种条件关系,而if语句可以判断多种条件关系

2、 实例

#!/bin/bash

#选择课程

echo "1 :  yuwen"

echo "2 :  shuxue"

echo "3 :  yingyu"

read -t 30 -p "choose kecheng:" cho

case $cho in

        "1")

                echo "choose yuwen."

                ;;

        "2")

                echo "choose shuxue."

                ;;

        "3")

                echo "choose yingyu"

                ;;

        *)

                echo "choose wrong"

                ;;

esac

6) for循环

1、 语法一

for 变量 in 值1 值2 值3…

     do

                程序

     done

2、 实例

#!/bin/bash

#批量解压缩脚本

cd /root/test/

ls *.tar.gz > ls.log

ls *.tgz >> ls.log

for i in $( cat ls.log )

do

tar -zxvf $i  & > /dev/null

(& > /dev/null所有输出的内容放进回收站,意思是解压文件将输出信息放入回收站中)

rm -rf ls.log

#删除 ls.log

3、 语法二

for ((初始值;循环控制条件;变量变化))

   do

         程序

   done

4、 实例

#!/bin/bash

#从1加到100

s=0

for ((i=1;i<=100;i=i+1))

        do

                s=$(($s+$i))

        done

echo $s

7) while循环和until循环

1、 while循环

while [条件判断式]

    do

                程序

    done

2、 until循环

until [条件判断式]

       do

                   程序

      done

 

3、  

 

posted @ 2017-07-05 20:41  赤道上的冰雕  阅读(456)  评论(0编辑  收藏  举报