10Shell脚本.docx
《10Shell脚本.docx》由会员分享,可在线阅读,更多相关《10Shell脚本.docx(16页珍藏版)》请在冰豆网上搜索。
10Shell脚本
第10章Shell脚本
1、Shell环境概述
(1)、临时切换Shell环境:
直接执行其他Shell程序,例如ksh、zsh等
bash:
Linux默认shell
sh:
FreeBSD默认shell
Kornsh:
Unix默认shell
Zsh:
前沿shell
(2)、永久更改用户登录Shell环境
需修改/etc/passwd文件中用户记录的最后一个字段
或执行:
usermod-sShell程序路径用户名
#cat/etc/shells
#chsh-l——列举可用shell,同/etc/shells
#chsh-s/bin/sh——修改自己的默认shell
#usermodchxcn-s/bin/sh——修改他人默认shell,修改自己的也必须加用户名!
(3)、Bash的常用功能
Tab键自动补齐
命令编辑快捷键
命令历史history
命令别名alias
标准输入输出
重定向操作(文件)<>>>2>2>>&>
管道操作(命令)|
2、Shell变量
(1)、Shell变量的各类
用户自定义变量
环境变量
预定义变量
位置变量
(2)、用户自定义变量
——定义新的变量(区分大小写),过去定义方法,要求=号两边都不能有空格,否则要加上引用符号
#DAY=Sunday
#DAY='Sunday'
#echo$DAY——显示变量的值
#echo${DAY}
#echo$DAY$
#Var=Benet&&echo${Var}3.0——加{}显示变量
#readDAY——从键盘输入内容为变量赋值
#read-p'Pleaseinputalitter!
'Litter——从键盘输入内容为变量赋值,并提示
#DAY="Todayis$DAY"——双引号"":
允许通过$符号引用其他变量值
#Money='Thepriceis$50'——单引号'':
禁止引用其他变量值,$视为普通字符
#DAY=`date+%Y%m%d`——反撇号``:
将命令执行的结果输出给变量
#exportFILESVR——定义为全局变量(默认为局部变量,导出后为环境变量)
#unsetFILESVR——重置变量,取消变量
#sum=100+300+50
#echo$sum
#declare-isum=100+300+50——declare–i定义为数值类型,否则为文本类型
#echo$sum
#num=`expr32\*10`——计算整数表达式的运算结果(+、-、\*、/、%)
——数组
#var[1]="smallmin"
#var[2]="bigmin"
#var[3]="nicemin"
#echo"${var[1]},${var[2]},${var[3]}"
注意1:
Linux里面变量都是字符串,哪怕是a=1这样的赋值,其实也是a='1',
从expr表达式计算符号两边都必须加空格,可以验证。
注意2:
export定义的全局变量只能在本次会话连接有效,对其它会话无效,
如果要定义的全局变量一直有效,必须定义在环境变量配置文件中。
3、环境变量
(1)、环境变量配置文件:
全局配置文件:
/etc/profile——对所有用户有效
用户配置文件:
~/.bash_profile——对当前用户用效,CUI
#env——查看所有的环境变量
#set——查看所有的Shell变量,其中包括环境变量
#PATH="/opt/bin:
$PATH"——改变搜索路径,注意写法!
!
常见环境变量:
$USER、$LOGNAME
$UID、$SHELL、$HOME
$PWD、$PATH
$PS1、$PS2
说明1:
$PS1:
默认提示符;
$PS2:
辅助提示符,第一行没输完,等待第二行输入的提示符。
说明2:
~/.bash_profile:
用户每次登录时执行
~/.bashrc:
每次进入新的Bash环境时执行,rc:
runcommand
~/.bash_logout:
用户每次退出登录时执行
(2)、变量的替换和删除
$echo${test1##test2}
——在变量test1中,从左开始,满足test2表达式的字符串全部删除
$echo${test1#test2}
——在变量test1中,从左开始,满足test2表达式的字符串删除一个
$echo${test1%%test2}
——在变量test1中,从右开始,满足test2表达式的字符串全部删除
$echo${test1%test2}
——在变量test1中,从右开始,满足test2表达式的字符串删除一个
$echo${test1//test2/test3}
——在变量test1中,把test2字符串全部替换为test3
$echo${test1/test2/test3}
——在变量test1中,找到第一个test2字符串,并替换为test3,仅一次
(3)、位置变量
#./exam01onetwothreefourfivesix
$1~$9——表示第1到9参数
$0——表示命令本身
(4)、预定义变量
$echo$?
——返回上一条命令的执行结果,0为正常,非0为错误
$echo$0$$——查看当前所执行进程的名称、PID号
4、Shell脚本的执行
4.1、建立包含执行语句的脚本文件
(1).脚本文件中包括的内容
①运行环境设置:
#!
/bin/bash指定默认脚本执行shell
②注释信息:
以#开始的说明性文字
③可执行的Linux命令行
(2).为脚本文件添加可执行权限
chmoda+x
42、运行Shell脚本程序
(1).直接执行具有“x”权限的脚本文件
例如:
./hello.sh
(2).使用指定的解释器程序执行脚本内容
例如:
bashhello.sh、shhello.sh(一般在调试阶段使用)
(3).通过source命令(或.)读取脚本内容执行
例如:
soucehello.sh或.hello.sh(点空格)
5、条件测试操作
(1)、test命令
用途:
测试特定的表达式是否成立,成立时为0,不成立非0
格式1:
test条件表达式
格式2:
[条件表达式]
注意:
test命令的两种方式的作用完全相同,但通常后一种形式更为常用,也更贴近编程习惯,;方括号“[”或者“]”与条件表达式语句之间至少需要有一个空格进行分隔
Exitstatus:
0:
iftheexpressionistrue,
1:
iftheexpressionisfalse,
2:
ifanerroroccurred.
(2)、测试文件状态
常用的测试操作符:
-d:
测试是否为目录(Directory)
-f:
测试是否为文件(File)
-L:
测试是否为符号链接文件(Link)同-h
-r:
测试当前用户是否有权限读取(Read)
-w:
测试当前用户是否有权限读取(Write)
-x:
测试当前用户是否可以执行该文件(Excute)
-k:
测试目录是否有粘滞位(Sticky)
-u:
测试可执行是否有用户SET位(set-user-ID)
-g:
测试可执行是否有组SET位(set-group-ID)
-O:
测试文件的属主是否为当前用户(Owner)
-G:
测试文件的属组是否为当前用户所属组()
-e:
测试目录或文件是否存在(Exist)
-s:
测试文件是否为非空(Size)
#[-d/etc/vsftpd]
#echo$?
——$?
为预定义变量,用于显示命令的执行结果
#[-e/media/cdrom]&&echo"YES"
——&&符号表示而且,当条件成立时才执行后面的语句,等价于if;||等价于ifnot;
#[-k/tmp]&&echo"YES"
#[-u/usr/bin/passwd]&&echo"YES"
说明:
&&,逻辑与、“AND”、而且的意思,解释&&作用
(3)、整数值比较
常用的测试操作符:
-eq:
等于(Equal)
-ne:
不等于(NotEqual)
-gt:
大于(GreaterThan)
-lt:
小于(LesserThan)
-le:
小于或等于(LesserorEqual)
-ge:
大于或等于(GreaterorEqual)
#[`who|wc-l`-le10]&&echo"YES"
#BootUsage=`df-hT|grep"/boot"|awk'{print$6}'|cut-d"%"-f1`
#[$BootUsage-gt95]&&echo"YES"
说明:
提前接触部分过滤器
df-hT——查看所有分区的磁盘空间使用情况
grep"/boot"——过滤出关于/boot分的数据行
awk'{print$6}'——以空格为分隔符,只取第六个字段数据
cut-d"%"-f1——以%为分隔符,只取第一个字段数据
(4)、字符串比较
常用的测试操作符:
=:
字符串内容相同
!
=:
字符串内容不同,!
号表示相反的意思
-z:
判断字符串内容为空(zore)
-n:
判断字符串内容非空(nonzore)
#read-p"Location:
"FilePath
Location:
/etc/inittab
#[$FilePath="/etc/inittab"]&&echo"YES"
#[$LANG!
="en.US"]&&echo$LANG
(5)、逻辑测试
格式:
[表达式1]操作符[表达式2]...
常用的测试操作符:
-a或&&:
逻辑与,"而且"的意思
前后两个表达式都成立时整个测试结果才为真,否则为假
-o或||:
逻辑或,"或者"的意思
操作符两边至少一个为真时,结果为真,否则结果为假
!
:
逻辑否
当指定的条件不成立时,返回结果为真
#echo$USER
root
#[$USER!
="teacher"]&&echo"Notteacher"
Notteacher
#[$USER="teacher"]||echo"Notteacher"
Notteacher
6、if条件语句
(1)、if条件语句——单分支
当"条件成立"时执行相应的操作
if条件测试命令
then命令序列
fi
范例:
如果/boot分区的空间使用超过80%,输出报警信息
#!
/bin/bash
RATE=`df-hT|grep"/boot"|awk'{print$6}'|cut-d"%"-f1`
if[$RATE-gt80]
then
echo"Warning,DISKisfull!
"
fi
(2)、if条件语句——双分支
当"条件成立"、"条件不成立"时执行不同操作
if条件测试命令
then命令序列1
else命令序列2
fi
范例:
判断mysqld是否在运行,若已运行则输出提示信息,否则重新启动mysqld服务
#!
/bin/bash
servicemysqldstatus&>/dev/null
if[$?
-eq0]
then
echo"mysqldserviceisrunning."
else
/etc/init.d/mysqldrestart
Fi
(3)、if条件语句——多分支
相当于if语句嵌套,针对多个条件执行不同操作
if条件测试命令1;then
命令序列1
elif条件测试命令2;then
命令序列2
elif...
else
命令序列n
fi
7、case多重分支语句
case变量值in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
……
*)
默认执行的命令序列
Esac
范例1:
编写脚本文件mydb.sh,用于控制系统服务mysqld
当执行./mydb.shstart时,启动mysqld服务
当执行./mydb.shstop时,关闭mysqld服务
如果输入其他脚本参数,则显示帮助信息
#!
/bin/bash
case$1in
start)
echo"StartMySQLservice."
;;
stop)
echo"StopMySQLservice."
;;
*)
echo"Usage:
$0start|stop"
;;
esac
范例2:
提示用户从键盘输入一个字符,判断该字符是否为字母、
数字或者其它字符,并输出相应的提示信息
#!
/bin/bash
read-p"Presssomekey,thenpressReturn:
"KEY
case"$KEY"in
[a-z]|[A-Z])
echo"It'saletter."
;;
[0-9])
echo"It'sadigit."
;;
*)
echo"It'sfunctionkeys、Spacebarorotherkeys."
esac
8、for循环语句
for变量名in取值列表
do
命令序列
Done
范例1:
依次输出3条文字信息,包括一天中的"Morning"、"Noon"、"Evening"字串
#!
/bin/bash
forTMin"Morning""Noon""Evening"
do
echo"The$TMoftheday."
Done
范例2:
对于使用"/bin/bash"作为登录Shell的系统用户,
检查他们在"/opt"目录中拥有的子目录或文件数量,
如果超过100个,则列出具体个数及对应的用户帐号。
#!
/bin/bash
DIR="/opt"
LMT=100
ValidUsers=`grep"/bin/bash"/etc/passwd|cut-d":
"-f1`
//获取使用"/bin/bash"作为登录Shell的系统用户列表
forUserNamein$ValidUsers
do
Num=`find$DIR-user$UserName|wc-l`
//检查各用户在"/opt"目录中拥有的子目录或文件数量
if[$Num-gt$LMT];then
echo"$UserNamehave$Numfiles."
fi
done
9、while循环语句
while命令或表达式
do
命令列表
Done
范例1:
批量添加20个系统用户帐号,用户名依次为"stu1"、"stu2"、……、"stu20"
这些用户的初始密码均设置为"123456"
#!
/bin/bash
i=1
while[$i-le20]
do
useraddstu$i
echo"123456"|passwd--stdinstu$i&>/dev/null//添加密码
i=`expr$i+1`
done
范例2:
批量删除上例中添加的20个系统用户帐号
#!
/bin/bash
i=1
while[$i-le20]
do
userdel-rstu$i
i=`expr$i+1`
done
10、until循环语句
until语句根据条件执行重复操作
until条件测试命令
do
命令序列
done
11、shift迁移语句(类似foreach)
用于迁移位置变量,将$1~$9依次向左传递
例如,若当前脚本程序获得的位置变量如下:
$1=file1、$2=file2、$3=file3、$4=file4
则执行一次shift命令后,各位置变量为:
$1=file2、$2=file3、$3=file4
再次执行shift命令后,各位置变量为:
$1=file3、$2=file4
范例:
通过命令行参数传递多个整数值,并计算总和。
#visumer.sh
#!
/bin/bash
Result=0
while[$#-gt0]
do
Result=`expr$Result+$1`
shift
done
echo"Thesumis:
$Result"
]
[root@localhost~]#./sumer.sh123456//验证脚本执行结果
Thesumis:
102
12、循环控制语句
(1)、break语句:
在for、while、until等循环语句中,用于跳出当前所在的循环体,执行循环体后的语句
(2)、continue语句:
在for、while、until等循环语句中,用于跳过循环体内余下的语句,
重新判断条件以便执行下一次循环
13、Shell函数应用
(1)、定义新的函数
function函数名{
命令序列
}
或
函数名(){
命令序列
}
(2)、调用已定义的函数
函数名
(3)、向函数内传递参数
函数名参数1参数2...
范例:
在脚本中定义一个加法函数,用于计算2个整数的和
调用该函数计算(12+34)、(56+789)的和
#!
/bin/bash
adder(){
echo`expr$1+$2`
}
#adder1234
#adder56789