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为空 |
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、